aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Access/Permissions.php4
-rw-r--r--Zotlabs/Daemon/Onepoll.php5
-rw-r--r--Zotlabs/Lib/Activity.php146
-rw-r--r--Zotlabs/Lib/ActivityStreams.php13
-rw-r--r--Zotlabs/Lib/Enotify.php8
-rw-r--r--Zotlabs/Lib/Libzot.php12
-rw-r--r--Zotlabs/Lib/ThreadItem.php4
-rw-r--r--Zotlabs/Module/Channel.php37
-rw-r--r--Zotlabs/Module/Display.php39
-rw-r--r--Zotlabs/Module/Dreport.php18
-rw-r--r--Zotlabs/Module/Hq.php26
-rw-r--r--Zotlabs/Module/Item.php4
-rw-r--r--Zotlabs/Module/Linkinfo.php190
-rw-r--r--Zotlabs/Module/Oep.php7
-rw-r--r--Zotlabs/Module/Pin.php2
-rw-r--r--Zotlabs/Module/Pubstream.php20
-rw-r--r--Zotlabs/Module/Sse_bs.php2
-rw-r--r--Zotlabs/Widget/Pinned.php58
18 files changed, 344 insertions, 251 deletions
diff --git a/Zotlabs/Access/Permissions.php b/Zotlabs/Access/Permissions.php
index df5472cc3..45dd30d69 100644
--- a/Zotlabs/Access/Permissions.php
+++ b/Zotlabs/Access/Permissions.php
@@ -65,9 +65,9 @@ class Permissions {
'write_wiki' => t('Can write to my wiki pages'),
'post_wall' => t('Can post on my channel (wall) page'),
'post_comments' => t('Can comment on or like my posts'),
- 'post_mail' => t('Can send me private mail messages'),
+ 'post_mail' => t('Can send me direct messages'),
'post_like' => t('Can like/dislike profiles and profile things'),
- 'tag_deliver' => t('Can forward to all my channel connections via ! mentions in posts'),
+ 'tag_deliver' => t('Can forward direct messages to all my channel connections (forum)'),
'chat' => t('Can chat with me'),
'republish' => t('Can source my public posts in derived channels'),
'delegate' => t('Can administer my channel')
diff --git a/Zotlabs/Daemon/Onepoll.php b/Zotlabs/Daemon/Onepoll.php
index 4aebf64b0..5374f49d5 100644
--- a/Zotlabs/Daemon/Onepoll.php
+++ b/Zotlabs/Daemon/Onepoll.php
@@ -126,7 +126,10 @@ class Onepoll {
$max = intval(get_config('system', 'max_imported_posts', 30));
if (intval($max)) {
- $cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
+ $cl = Activity::get_actor_collections($contact['abook_xchan']);
+ if(empty($cl)) {
+ $cl = get_xconfig($contact['abook_xchan'], 'activitypub', 'collections');
+ }
if (is_array($cl) && array_key_exists('outbox', $cl)) {
$url = $cl['outbox'];
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index 4f63b31da..62a22f70e 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -8,6 +8,8 @@ use Zotlabs\Access\PermissionRoles;
use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Master;
use Zotlabs\Web\HTTPSig;
+use Zotlabs\Lib\XConfig;
+use Zotlabs\Lib\Libzot;
require_once('include/event.php');
require_once('include/html2plain.php');
@@ -1109,6 +1111,7 @@ class Activity {
call_hooks('encode_person', $arr);
$ret = $arr['encoded'];
+
return $ret;
}
@@ -1537,6 +1540,49 @@ class Activity {
return;
}
+/* not implemented
+ if (array_key_exists('movedTo',$person_obj) && $person_obj['movedTo'] && ! is_array($person_obj['movedTo'])) {
+ $tgt = self::fetch($person_obj['movedTo']);
+ if (is_array($tgt)) {
+ self::actor_store($person_obj['movedTo'],$tgt);
+ ActivityPub::move($person_obj['id'],$tgt);
+ }
+ return;
+ }
+*/
+ $ap_hubloc = null;
+
+ $hublocs = self::get_actor_hublocs($url);
+
+ if ($hublocs) {
+ foreach ($hublocs as $hub) {
+ if ($hub['hubloc_network'] === 'activitypub') {
+ $ap_hubloc = $hub;
+ }
+ if ($hub['hubloc_network'] === 'zot6') {
+ Libzot::update_cached_hubloc($hub);
+ }
+ }
+ }
+
+ if ($ap_hubloc) {
+ // we already have a stored record. Determine if it needs updating.
+ if ($ap_hubloc['hubloc_updated'] < datetime_convert('UTC','UTC',' now - 3 days') || $force) {
+ $person_obj = self::fetch($url);
+ }
+ else {
+ return;
+ }
+ }
+
+ if (isset($person_obj['id'])) {
+ $url = $person_obj['id'];
+ }
+
+ if (! $url) {
+ return;
+ }
+
$inbox = $person_obj['inbox'];
// invalid identity
@@ -1545,6 +1591,9 @@ class Activity {
return;
}
+ // store the actor record in XConfig
+ XConfig::Set($url, 'system', 'actor_record', $person_obj);
+
$name = $person_obj['name'];
if (!$name) {
$name = $person_obj['preferredUsername'];
@@ -1603,20 +1652,6 @@ class Activity {
$profile = $url;
}
- $collections = [];
-
- if ($inbox) {
- $collections['inbox'] = $inbox;
- if (array_key_exists('outbox', $person_obj))
- $collections['outbox'] = $person_obj['outbox'];
- if (array_key_exists('followers', $person_obj))
- $collections['followers'] = $person_obj['followers'];
- if (array_key_exists('following', $person_obj))
- $collections['following'] = $person_obj['following'];
- if (array_key_exists('endpoints', $person_obj) && array_key_exists('sharedInbox', $person_obj['endpoints']))
- $collections['sharedInbox'] = $person_obj['endpoints']['sharedInbox'];
- }
-
if (array_key_exists('publicKey', $person_obj) && array_key_exists('publicKeyPem', $person_obj['publicKey'])) {
if ($person_obj['id'] === $person_obj['publicKey']['owner']) {
$pubkey = $person_obj['publicKey']['publicKeyPem'];
@@ -1702,10 +1737,6 @@ class Activity {
);
}
- if ($collections) {
- set_xconfig($url, 'activitypub', 'collections', $collections);
- }
-
$photos = import_xchan_photo($icon, $url);
q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbescdate(datetime_convert('UTC', 'UTC', $photos[5])),
@@ -1784,12 +1815,27 @@ class Activity {
}
else {
if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'send_stream') && !$is_sys_channel) {
- logger('no permission');
+ logger('no send_stream permission');
return;
}
$s['owner_xchan'] = $s['author_xchan'] = $observer_hash;
}
+ if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips)))
+ $s['item_private'] = 1;
+
+
+ if (array_key_exists('directMessage', $act->obj) && intval($act->obj['directMessage'])) {
+ $s['item_private'] = 2;
+ }
+
+ if (intval($s['item_private']) === 2) {
+ if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'post_mail')) {
+ logger('no post_mail permission');
+ return;
+ }
+ }
+
$abook = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($observer_hash),
intval($channel['channel_id'])
@@ -1938,14 +1984,6 @@ class Activity {
}
}
- if ($act->recips && (!in_array(ACTIVITY_PUBLIC_INBOX, $act->recips)))
- $s['item_private'] = 1;
-
-
- if (array_key_exists('directMessage', $act->obj) && intval($act->obj['directMessage'])) {
- $s['item_private'] = 2;
- }
-
set_iconfig($s, 'activitypub', 'recips', $act->raw_recips);
if ($parent) {
set_iconfig($s, 'activitypub', 'rawmsg', $act->raw, 1);
@@ -2641,6 +2679,11 @@ class Activity {
$allowed = true;
}
+ if (intval($item['item_private']) === 2) {
+ if (!perm_is_allowed($channel['channel_id'], $observer_hash, 'post_mail')) {
+ $allowed = false;
+ }
+ }
if ($is_sys_channel) {
@@ -3504,4 +3547,53 @@ class Activity {
}
+ static function get_cached_actor($id) {
+ return (XConfig::Get($id,'system','actor_record'));
+ }
+
+ static function get_actor_hublocs($url, $options = 'all') {
+
+ $hublocs = false;
+
+ switch ($options) {
+ case 'activitypub':
+ $hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_hash = '%s' and hubloc_deleted = 0 ",
+ dbesc($url)
+ );
+ break;
+ case 'zot6':
+ $hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_id_url = '%s' and hubloc_deleted = 0 ",
+ dbesc($url)
+ );
+ break;
+ case 'all':
+ default:
+ $hublocs = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where ( hubloc_id_url = '%s' OR hubloc_hash = '%s' ) and hubloc_deleted = 0 ",
+ dbesc($url),
+ dbesc($url)
+ );
+ break;
+ }
+
+ return $hublocs;
+ }
+
+ static function get_actor_collections($url) {
+ $ret = [];
+ $actor_record = XConfig::Get($url,'system','actor_record');
+ if (! $actor_record) {
+ return $ret;
+ }
+
+ foreach ( [ 'inbox','outbox','followers','following' ] as $collection) {
+ if (isset($actor_record[$collection]) && $actor_record[$collection]) {
+ $ret[$collection] = $actor_record[$collection];
+ }
+ }
+ if (array_path_exists('endpoints/sharedInbox',$actor_record) && $actor_record['endpoints']['sharedInbox']) {
+ $ret['sharedInbox'] = $actor_record['endpoints']['sharedInbox'];
+ }
+
+ return $ret;
+ }
}
diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php
index 2324a8136..fa38c569e 100644
--- a/Zotlabs/Lib/ActivityStreams.php
+++ b/Zotlabs/Lib/ActivityStreams.php
@@ -300,17 +300,8 @@ class ActivityStreams {
function get_actor($property, $base = '', $namespace = '') {
$x = $this->get_property_obj($property, $base, $namespace);
if ($this->is_url($x)) {
-
- // SECURITY: If we have already stored the actor profile, re-generate it
- // from cached data - don't refetch it from the network
-
- $r = q("select * from xchan join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s'",
- dbesc($x)
- );
- if ($r) {
- $r = Libzot::zot_record_preferred($r);
- $y = Activity::encode_person($r);
- $y['cached'] = true;
+ $y = Activity::get_cached_actor($x);
+ if ($y) {
return $y;
}
}
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index 7d741edd8..632848290 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -854,8 +854,8 @@ class Enotify {
'photo' => $item[$who]['xchan_photo_s'],
'when' => (($edit) ? datetime_convert('UTC', date_default_timezone_get(), $item['edited']) : datetime_convert('UTC', date_default_timezone_get(), $item['created'])),
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
- 'b64mid' => (($item['mid']) ? 'b64.' . base64url_encode($item['mid']) : ''),
- //'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
+ 'b64mid' => (($item['mid']) ? gen_link_id($item['mid']) : ''),
+ //'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? gen_link_id($item['thr_parent']) : gen_link_id($item['mid'])),
'thread_top' => (($item['item_thread_top']) ? true : false),
'message' => bbcode(escape_tags($itemem_text)),
'body' => htmlentities(html2plain(bbcode($item['body'], ['drop_media', true]), 75, true), ENT_QUOTES, 'UTF-8', false),
@@ -882,7 +882,7 @@ class Enotify {
$mid = basename($tt['link']);
- $b64mid = ((strpos($mid, 'b64.') === 0) ? $mid : 'b64.' . base64url_encode($mid));
+ $b64mid = gen_link_id($mid);
$x = [
'notify_link' => (($tt['ntype'] === NOTIFY_MAIL) ? $tt['link'] : z_root() . '/notify/view/' . $tt['id']),
'name' => $tt['xname'],
@@ -910,7 +910,7 @@ class Enotify {
'when' => datetime_convert('UTC', date_default_timezone_get(), $rr['abook_created']),
'hclass' => ('notify-unseen'),
'message' => t('added your channel')
- ];
+ ];
}
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index f7d8c417a..9c232f34d 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -1601,6 +1601,12 @@ class Libzot {
$friendofriend = true;
}
+ if (intval($arr['item_private']) === 2) {
+ if (!perm_is_allowed($channel['channel_id'], $sender, 'post_mail')) {
+ $allowed = false;
+ }
+ }
+
if (!$allowed) {
logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}");
$DR->update('permission denied');
@@ -3154,4 +3160,10 @@ class Libzot {
}
+ static function update_cached_hubloc($hubloc) {
+ if ($hubloc['hubloc_updated'] > datetime_convert('UTC','UTC','now - 1 week') || $hubloc['hubloc_url'] === z_root()) {
+ return;
+ }
+ self::refresh( [ 'hubloc_id_url' => $hubloc['hubloc_id_url'] ] );
+ }
}
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index c9048cd4f..cd54fea17 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -503,7 +503,7 @@ class ThreadItem {
'wait' => t('Please wait'),
'thread_level' => $thread_level,
'settings' => $settings,
- 'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? 'b64.' . base64url_encode($item['thr_parent']) : '')
+ 'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? gen_link_id($item['thr_parent']) : '')
);
$arr = array('item' => $item, 'output' => $tmp_item);
@@ -842,7 +842,7 @@ class ThreadItem {
'$cipher' => $conv->get_cipher(),
'$sourceapp' => \App::$sourcename,
'$observer' => get_observer_hash(),
- '$anoncomments' => ((($conv->get_mode() === 'channel' || $conv->get_mode() === 'display') && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
+ '$anoncomments' => ((in_array($conv->get_mode(), ['channel', 'display', 'cards', 'articles']) && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
'$anonname' => [ 'anonname', t('Your full name (required)') ],
'$anonmail' => [ 'anonmail', t('Your email address (required)') ],
'$anonurl' => [ 'anonurl', t('Your website URL (optional)') ]
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index 6fac610aa..34e1ea666 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -107,13 +107,11 @@ class Channel extends Controller {
// Somebody may attempt an ActivityStreams fetch on one of our message permalinks
// Make it do the right thing.
- $mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
- if ($mid && strpos($mid, 'b64.') === 0) {
- $decoded = @base64url_decode(substr($mid, 4));
- if ($decoded) {
- $mid = $decoded;
- }
+ $mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
+ if ($mid === false) {
+ http_status_exit(404, 'Not found');
}
+
if ($mid) {
$obj = null;
if (strpos($mid, z_root() . '/item/') === 0) {
@@ -158,15 +156,19 @@ class Channel extends Controller {
profile_load($which, $profile);
// Add Opengraph markup
- $mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
- if (strpos($mid, 'b64.') === 0)
- $mid = @base64url_decode(substr($mid, 4));
+ $mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
- if ($mid)
+ if ($mid === false) {
+ notice(t('Malformed message id.') . EOL);
+ return;
+ }
+
+ if ($mid) {
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
dbesc($mid),
intval($channel['channel_id'])
);
+ }
opengraph_add_meta((isset($r) && count($r) ? $r[0] : []), $channel);
}
@@ -177,12 +179,11 @@ class Channel extends Controller {
$category = $datequery = $datequery2 = '';
- $mid = ((x($_REQUEST, 'mid')) ? $_REQUEST['mid'] : '');
-
- if (strpos($mid, 'b64.') === 0)
- $decoded = @base64url_decode(substr($mid, 4));
- if (isset($decoded))
- $mid = $decoded;
+ $mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
+ if ($mid === false) {
+ notice(t('Malformed message id.') . EOL);
+ return;
+ }
$datequery = ((x($_GET, 'dend') && is_a_date_arg($_GET['dend'])) ? notags($_GET['dend']) : '');
$datequery2 = ((x($_GET, 'dbegin') && is_a_date_arg($_GET['dbegin'])) ? notags($_GET['dbegin']) : '');
@@ -433,8 +434,8 @@ class Channel extends Controller {
if ((!$update) && (!$load)) {
- if (isset($decoded))
- $mid = 'b64.' . base64url_encode($mid);
+ //if we got a decoded hash we must encode it again before handing to javascript
+ $mid = gen_link_id($mid);
// This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
// because browser prefetching might change it on us. We have to deliver it with the page.
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index e6caa9906..5ffb1346c 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
+use App;
+
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
@@ -34,11 +36,12 @@ class Display extends \Zotlabs\Web\Controller {
}
}
- if($_REQUEST['mid'])
- $item_hash = $_REQUEST['mid'];
+ if($_REQUEST['mid']) {
+ $item_hash = unpack_link_id($_REQUEST['mid']);
+ }
- if(! $item_hash) {
- \App::$error = 404;
+ if(!$item_hash) {
+ App::$error = 404;
notice( t('Item not found.') . EOL);
return;
}
@@ -47,7 +50,7 @@ class Display extends \Zotlabs\Web\Controller {
if(local_channel() && (! $update)) {
- $channel = \App::get_channel();
+ $channel = App::get_channel();
$channel_acl = array(
'allow_cid' => $channel['channel_allow_cid'],
@@ -92,10 +95,10 @@ class Display extends \Zotlabs\Web\Controller {
$target_item = null;
- if(strpos($item_hash,'b64.') === 0)
- $decoded = @base64url_decode(substr($item_hash,4));
- if($decoded)
- $item_hash = $decoded;
+ if ($item_hash === false) {
+ notice(t('Malformed message id.') . EOL);
+ return;
+ }
$r = q("select id, uid, mid, parent, parent_mid, thr_parent, verb, item_type, item_deleted, author_xchan, item_blocked from item where mid = '%s' limit 1",
dbesc($item_hash)
@@ -110,7 +113,7 @@ class Display extends \Zotlabs\Web\Controller {
);
if($x) {
// not yet ready for prime time
-// \App::$poi = $x[0];
+// App::$poi = $x[0];
}
//if the item is to be moderated redirect to /moderate
@@ -189,17 +192,15 @@ class Display extends \Zotlabs\Web\Controller {
// if the target item is not a post (eg a like) we want to address its thread parent
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
- $mid = $target_item['mid'];
// if we got a decoded hash we must encode it again before handing to javascript
- if($decoded)
- $mid = 'b64.' . base64url_encode($mid);
+ $mid = gen_link_id($target_item['mid']);
$o .= '<div id="live-display"></div>' . "\r\n";
$o .= "<script> var profile_uid = " . ((intval(local_channel())) ? local_channel() : (-1))
- . "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
+ . "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
- \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
+ App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
'$pgtype' => 'display',
'$uid' => '0',
@@ -215,7 +216,7 @@ class Display extends \Zotlabs\Web\Controller {
'$dm' => '0',
'$nouveau' => '0',
'$wall' => '0',
- '$page' => ((\App::$pager['page'] != 1) ? \App::$pager['page'] : 1),
+ '$page' => ((App::$pager['page'] != 1) ? App::$pager['page'] : 1),
'$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
'$search' => '',
'$xchan' => '',
@@ -233,7 +234,7 @@ class Display extends \Zotlabs\Web\Controller {
head_add_link([
'rel' => 'alternate',
'type' => 'application/json+oembed',
- 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
+ 'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . App::$query_string),
'title' => 'oembed'
]);
@@ -355,7 +356,7 @@ class Display extends \Zotlabs\Web\Controller {
}
$o .= '</noscript>';
- \App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . \App::$page['title'] : \App::$page['title']);
+ App::$page['title'] = (($items[0]['title']) ? $items[0]['title'] . " - " . App::$page['title'] : App::$page['title']);
$o .= conversation($items, 'display', $update, 'client');
}
@@ -368,7 +369,7 @@ class Display extends \Zotlabs\Web\Controller {
'$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
'$generator' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
'$generator_uri' => 'https://hubzilla.org',
- '$feed_id' => xmlify(\App::$cmd),
+ '$feed_id' => xmlify(App::$cmd),
'$feed_title' => xmlify(t('Article')),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
'$author' => '',
diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php
index 8906a4f81..42f337b76 100644
--- a/Zotlabs/Module/Dreport.php
+++ b/Zotlabs/Module/Dreport.php
@@ -12,24 +12,12 @@ class Dreport extends \Zotlabs\Web\Controller {
}
$table = 'item';
-
$channel = \App::get_channel();
+ $mid = ((argc() > 1) ? unpack_link_id(argv(1)) : '');
- $mid = ((argc() > 1) ? argv(1) : '');
- $encoded_mid = '';
-
- if(strpos($mid,'b64.') === 0) {
- $encoded_mid = $mid;
- $mid = @base64url_decode(substr($mid,4));
- }
if($mid === 'push') {
$table = 'push';
- $mid = ((argc() > 2) ? argv(2) : '');
-
- if(strpos($mid,'b64.') === 0) {
- $encoded_mid = $mid;
- $mid = @base64url_decode(substr($mid,4));
- }
+ $mid = ((argc() > 2) ? unpack_link_id(argv(2)) : '');
if($mid) {
$i = q("select id from item where mid = '%s' and uid = %d and ( author_xchan = '%s' or ( owner_xchan = '%s' and item_wall = 1 )) ",
@@ -43,7 +31,7 @@ class Dreport extends \Zotlabs\Web\Controller {
}
}
sleep(3);
- goaway(z_root() . '/dreport/' . (($encoded_mid) ? $encoded_mid : $mid));
+ goaway(z_root() . '/dreport/' . gen_link_id($mid));
}
if(! $mid) {
diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php
index 8c126d154..929f2b758 100644
--- a/Zotlabs/Module/Hq.php
+++ b/Zotlabs/Module/Hq.php
@@ -23,15 +23,21 @@ class Hq extends \Zotlabs\Web\Controller {
function get($update = 0, $load = false) {
- if(!local_channel())
+ if(!local_channel()) {
return;
+ }
if(argc() > 1 && argv(1) !== 'load') {
- $item_hash = argv(1);
+ $item_hash = unpack_link_id(argv(1));
}
if(isset($_REQUEST['mid'])) {
- $item_hash = $_REQUEST['mid'];
+ $item_hash = unpack_link_id($_REQUEST['mid']);
+ }
+
+ if($item_hash === false) {
+ notice(t('Malformed message id.') . EOL);
+ return;
}
$item_normal = item_normal();
@@ -41,22 +47,17 @@ class Hq extends \Zotlabs\Web\Controller {
$r = q("SELECT mid FROM item
WHERE uid = %d $item_normal
AND mid = parent_mid
+ AND item_private IN (0, 1)
ORDER BY created DESC LIMIT 1",
intval(local_channel())
);
if($r[0]['mid']) {
- $item_hash = 'b64.' . base64url_encode($r[0]['mid']);
+ $item_hash = $r[0]['mid'];
}
}
if($item_hash) {
- if(strpos($item_hash,'b64.') === 0)
- $decoded = @base64url_decode(substr($item_hash,4));
-
- if($decoded)
- $item_hash = $decoded;
-
$target_item = null;
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid = '%s' limit 1",
@@ -124,10 +125,9 @@ class Hq extends \Zotlabs\Web\Controller {
if($target_item) {
// if the target item is not a post (eg a like) we want to address its thread parent
//$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
- $mid = $target_item['mid'];
+
// if we got a decoded hash we must encode it again before handing to javascript
- if($decoded)
- $mid = 'b64.' . base64url_encode($mid);
+ $mid = gen_link_id($target_item['mid']);
}
else {
$mid = '';
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 0e76755a8..7099a54e5 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -1377,6 +1377,10 @@ class Item extends Controller {
return $post;
if($return_path) {
+ if($return_path === 'hq') {
+ goaway(z_root() . '/hq/' . gen_link_id($datarray['mid']));
+ }
+
goaway(z_root() . "/" . $return_path);
}
diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php
index 76c679cc5..a05575cb6 100644
--- a/Zotlabs/Module/Linkinfo.php
+++ b/Zotlabs/Module/Linkinfo.php
@@ -5,37 +5,37 @@ namespace Zotlabs\Module;
class Linkinfo extends \Zotlabs\Web\Controller {
function get() {
-
+
logger('linkinfo: ' . print_r($_REQUEST,true));
-
+
$text = null;
$str_tags = '';
- $process_oembed = true;
-
+ $process_oembed = true;
+
$br = "\n";
-
+
if(x($_GET,'binurl'))
$url = trim(hex2bin($_GET['binurl']));
else
$url = trim($_GET['url']);
-
+
if(substr($url,0,1) === '!') {
$process_oembed = false;
$url = substr($url,1);
}
$url = strip_zids($url);
-
+
if((substr($url,0,1) != '/') && (substr($url,0,4) != 'http'))
$url = 'http://' . $url;
-
-
+
+
if($_GET['title'])
$title = strip_tags(trim($_GET['title']));
-
+
if($_GET['description'])
$text = strip_tags(trim($_GET['description']));
-
+
if($_GET['tags']) {
$arr_tags = str_getcsv($_GET['tags']);
if(count($arr_tags)) {
@@ -43,23 +43,25 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$str_tags = $br . implode(' ',$arr_tags) . $br;
}
}
-
+
logger('linkinfo: ' . $url);
-
- // Replace plink URL with 'share' tag if possible
- preg_match("/(mid=b64\.|display\/|posts\/)([\w\-]+)(&.+)?$/", $url, $mid);
-
- if (!empty($mid) && $mid[1] == 'mid=b64.')
- $mid[2] = base64_decode($mid[2]);
-
- $r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
- dbesc((empty($mid) ? $url : $mid[2])),
- intval(local_channel())
- );
- if ($r) {
- echo "[share=" . $r[0]['id'] . "][/share]";
- killme();
- }
+
+ // Replace plink URL with 'share' tag if possible
+ preg_match("/(mid=b64\.|display\/|posts\/)([\w\-]+)(&.+)?$/", $url, $mid);
+
+ if (!empty($mid)) {
+ $mid[2] = unpack_link_id($mid[2]);
+ }
+
+ $r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d AND item_private = 0 LIMIT 1",
+ dbesc((empty($mid) ? $url : $mid[2])),
+ intval(local_channel())
+ );
+
+ if ($r) {
+ echo "[share=" . $r[0]['id'] . "][/share]";
+ killme();
+ }
$result = z_fetch_url($url,false,0,array('novalidate' => true, 'nobody' => true));
if($result['success']) {
@@ -108,13 +110,13 @@ class Linkinfo extends \Zotlabs\Web\Controller {
}
}
}
-
+
$template = $br . '#^[url=%s]%s[/url]%s' . $br;
-
+
$arr = array('url' => $url, 'text' => '');
-
+
call_hooks('parse_link', $arr);
-
+
if(strlen($arr['text'])) {
echo $arr['text'];
killme();
@@ -127,28 +129,28 @@ class Linkinfo extends \Zotlabs\Web\Controller {
killme();
}
}
-
+
if($url && $title && $text) {
-
+
$text = $br . '[quote]' . trim($text) . '[/quote]' . $br;
-
+
$title = str_replace(array("\r","\n"),array('',''),$title);
-
+
$result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags;
-
+
logger('linkinfo (unparsed): returns: ' . $result);
-
+
echo $result;
killme();
}
-
+
$siteinfo = self::parseurl_getsiteinfo($url);
-
+
// If the site uses this platform, use zrl rather than url so they get zids sent to them by default
-
+
if(is_matrix_url($url))
$template = str_replace('url','zrl',$template);
-
+
if($siteinfo["title"] == "") {
echo sprintf($template,$url,$url,'') . $str_tags;
killme();
@@ -156,19 +158,19 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$text = $siteinfo["text"];
$title = $siteinfo["title"];
}
-
+
$image = "";
if(is_array($siteinfo["images"]) && count($siteinfo["images"])){
/* Execute below code only if image is present in siteinfo */
-
+
$total_images = 0;
$max_images = get_config('system','max_bookmark_images');
if($max_images === false)
$max_images = 2;
else
$max_images = intval($max_images);
-
+
foreach ($siteinfo["images"] as $imagedata) {
if ($url) {
$image .= sprintf('[url=%s]', $url);
@@ -183,57 +185,57 @@ class Linkinfo extends \Zotlabs\Web\Controller {
break;
}
}
-
+
if(strlen($text)) {
$text = $br.'[quote]'.trim($text).'[/quote]'.$br ;
}
-
+
if($image) {
$text = $br.$br.$image.$text;
}
$title = str_replace(array("\r","\n"),array('',''),$title);
-
+
$result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags;
-
+
logger('linkinfo: returns: ' . $result, LOGGER_DEBUG);
-
+
echo trim($result);
killme();
-
+
}
-
-
+
+
public static function deletexnode(&$doc, $node) {
$xpath = new \DomXPath($doc);
$list = $xpath->query("//".$node);
foreach ($list as $child)
$child->parentNode->removeChild($child);
}
-
+
public static function completeurl($url, $scheme) {
$urlarr = parse_url($url);
-
+
if (isset($urlarr["scheme"]))
return($url);
-
+
$schemearr = parse_url($scheme);
-
+
$complete = $schemearr["scheme"]."://".$schemearr["host"];
-
+
if ($schemearr["port"] != "")
$complete .= ":".$schemearr["port"];
-
+
if(strpos($urlarr['path'],'/') !== 0)
$complete .= '/';
-
+
$complete .= $urlarr["path"];
-
+
if ($urlarr["query"] != "")
$complete .= "?".$urlarr["query"];
-
+
if ($urlarr["fragment"] != "")
$complete .= "#".$urlarr["fragment"];
-
+
return($complete);
}
@@ -251,7 +253,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$p = substr($m,strpos($m,'/')+1);
// get the channel to check permissions
-
+
$u = channelx_by_nick($nick);
if($u && $p) {
@@ -272,18 +274,18 @@ class Linkinfo extends \Zotlabs\Web\Controller {
return EMPTY_STR;
}
-
+
public static function parseurl_getsiteinfo($url) {
$siteinfo = array();
-
-
+
+
$result = z_fetch_url($url,false,0,array('novalidate' => true));
if(! $result['success'])
return $siteinfo;
-
+
$header = $result['header'];
$body = $result['body'];
-
+
// Check codepage in HTTP headers or HTML if not exist
$cp = (preg_match('/Content-Type: text\/html; charset=(.+)\r\n/i', $header, $o) ? $o[1] : '');
if(empty($cp))
@@ -291,10 +293,10 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$body = mb_convert_encoding($body, 'UTF-8', $cp);
$body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8");
-
+
$doc = new \DOMDocument();
@$doc->loadHTML($body);
-
+
self::deletexnode($doc, 'style');
self::deletexnode($doc, 'script');
self::deletexnode($doc, 'option');
@@ -306,14 +308,14 @@ class Linkinfo extends \Zotlabs\Web\Controller {
self::deletexnode($doc, 'h6');
self::deletexnode($doc, 'ol');
self::deletexnode($doc, 'ul');
-
+
$xpath = new \DomXPath($doc);
-
+
//$list = $xpath->query("head/title");
$list = $xpath->query("//title");
foreach ($list as $node)
$siteinfo["title"] = html_entity_decode($node->nodeValue, ENT_QUOTES, "UTF-8");
-
+
//$list = $xpath->query("head/meta[@name]");
$list = $xpath->query("//meta[@name]");
foreach ($list as $node) {
@@ -321,9 +323,9 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
-
+
$attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8");
-
+
switch (strtolower($attr["name"])) {
case "fulltitle":
$siteinfo["title"] = trim($attr["content"]);
@@ -365,7 +367,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
break;
}
}
-
+
//$list = $xpath->query("head/meta[@property]");
$list = $xpath->query("//meta[@property]");
foreach ($list as $node) {
@@ -373,9 +375,9 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
-
+
$attr["content"] = html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8");
-
+
switch (strtolower($attr["property"])) {
case "og:image":
$siteinfo["image"] = $attr["content"];
@@ -388,7 +390,7 @@ class Linkinfo extends \Zotlabs\Web\Controller {
break;
}
}
-
+
if ($siteinfo["image"] == "") {
$list = $xpath->query("//img[@src]");
foreach ($list as $node) {
@@ -396,10 +398,10 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
-
+
$src = self::completeurl($attr["src"], $url);
$photodata = @getimagesize($src);
-
+
if (($photodata) && ($photodata[0] > 150) and ($photodata[1] > 150)) {
if ($photodata[0] > 300) {
$photodata[1] = round($photodata[1] * (300 / $photodata[0]));
@@ -413,36 +415,36 @@ class Linkinfo extends \Zotlabs\Web\Controller {
"width"=>$photodata[0],
"height"=>$photodata[1]);
}
-
+
}
} else {
$src = self::completeurl($siteinfo["image"], $url);
-
+
unset($siteinfo["image"]);
-
+
$photodata = @getimagesize($src);
-
+
if (($photodata) && ($photodata[0] > 10) and ($photodata[1] > 10))
$siteinfo["images"][] = array("src"=>$src,
"width"=>$photodata[0],
"height"=>$photodata[1]);
}
-
+
if ($siteinfo["text"] == "") {
$text = "";
-
+
$list = $xpath->query("//div[@class='article']");
foreach ($list as $node)
if (strlen($node->nodeValue) > 40)
$text .= " ".trim($node->nodeValue);
-
+
if ($text == "") {
$list = $xpath->query("//div[@class='content']");
foreach ($list as $node)
if (strlen($node->nodeValue) > 40)
$text .= " ".trim($node->nodeValue);
}
-
+
// If none text was found then take the paragraph content
if ($text == "") {
$list = $xpath->query("//p");
@@ -450,21 +452,21 @@ class Linkinfo extends \Zotlabs\Web\Controller {
if (strlen($node->nodeValue) > 40)
$text .= " ".trim($node->nodeValue);
}
-
+
if ($text != "") {
$text = trim(str_replace(array("\n", "\r"), array(" ", " "), $text));
-
+
while (strpos($text, " "))
$text = trim(str_replace(" ", " ", $text));
-
+
$text = substr(html_entity_decode($text, ENT_QUOTES, "UTF-8"), 0, 350);
$siteinfo["text"] = rtrim(substr($text, 0, strrpos($text, " ")), "?.,:;!-") . '...';
}
}
-
+
return($siteinfo);
}
-
+
private static function arr_add_hashes(&$item,$k) {
$item = '#' . $item;
diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php
index 346bef519..8e048a487 100644
--- a/Zotlabs/Module/Oep.php
+++ b/Zotlabs/Module/Oep.php
@@ -77,8 +77,11 @@ class Oep extends \Zotlabs\Web\Controller {
$res = $matches[2];
}
- if(strpos($res,'b64.') === 0) {
- $res = base64url_decode(substr($res,4));
+ $res = unpack_link_id($res);
+
+ if ($res === false) {
+ notice(t('Malformed message id.') . EOL);
+ return;
}
$item_normal = item_normal();
diff --git a/Zotlabs/Module/Pin.php b/Zotlabs/Module/Pin.php
index e02fb017b..f82327ce6 100644
--- a/Zotlabs/Module/Pin.php
+++ b/Zotlabs/Module/Pin.php
@@ -37,7 +37,7 @@ class Pin extends \Zotlabs\Web\Controller {
http_status_exit(404, 'Not found');
}
- $midb64 = 'b64.' . base64url_encode($r[0]['mid']);
+ $midb64 = gen_link_id($r[0]['mid']);
$pinned = (in_array($midb64, get_pconfig($r[0]['uid'], 'pinned', $r[0]['item_type'], [])) ? true : false);
switch(argv(1)) {
diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php
index 32023d6cc..e1a95be67 100644
--- a/Zotlabs/Module/Pubstream.php
+++ b/Zotlabs/Module/Pubstream.php
@@ -42,19 +42,16 @@ class Pubstream extends \Zotlabs\Web\Controller {
$site_firehose = false;
}
- $mid = ((x($_REQUEST,'mid')) ? $_REQUEST['mid'] : '');
- $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
-
-
- if(strpos($mid,'b64.') === 0)
- $decoded = @base64url_decode(substr($mid,4));
- if($decoded)
- $mid = $decoded;
+ $mid = ((x($_REQUEST, 'mid')) ? unpack_link_id($_REQUEST['mid']) : '');
+ if ($mid === false) {
+ notice(t('Malformed message id.') . EOL);
+ return;
+ }
+ $hashtags = ((x($_REQUEST,'tag')) ? $_REQUEST['tag'] : '');
$item_normal = item_normal();
$item_normal_update = item_normal_update();
-
- $net = ((array_key_exists('net',$_REQUEST)) ? escape_tags($_REQUEST['net']) : '');
+ $net = ((array_key_exists('net',$_REQUEST)) ? escape_tags($_REQUEST['net']) : '');
$title = replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => (($hashtags) ? '#' . htmlspecialchars($hashtags, ENT_COMPAT,'UTF-8') : '')
@@ -115,8 +112,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
. "; divmore_height = " . intval($maxheight) . "; </script>\r\n";
//if we got a decoded hash we must encode it again before handing to javascript
- if($decoded)
- $mid = 'b64.' . base64url_encode($mid);
+ $mid = gen_link_id($mid);
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),array(
'$baseurl' => z_root(),
diff --git a/Zotlabs/Module/Sse_bs.php b/Zotlabs/Module/Sse_bs.php
index 388a9ba4d..b445b235d 100644
--- a/Zotlabs/Module/Sse_bs.php
+++ b/Zotlabs/Module/Sse_bs.php
@@ -560,7 +560,7 @@ class Sse_bs extends Controller {
$b64mids = [];
foreach($mids as $mid)
- $b64mids[] = 'b64.' . base64url_encode($mid);
+ $b64mids[] = gen_link_id($mid);
$forums[$x]['notify_link'] = z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id'];
$forums[$x]['name'] = $forums[$x]['xchan_name'];
diff --git a/Zotlabs/Widget/Pinned.php b/Zotlabs/Widget/Pinned.php
index cad139a91..66d06bbd3 100644
--- a/Zotlabs/Widget/Pinned.php
+++ b/Zotlabs/Widget/Pinned.php
@@ -40,15 +40,15 @@ class Pinned {
$observer = \App::get_observer();
foreach($items as $item) {
-
- $midb64 = 'b64.' . base64url_encode($item['mid']);
-
+
+ $midb64 = gen_link_id($item['mid']);
+
if(isset($observer['xchan_hash']) && in_array($observer['xchan_hash'], get_pconfig($item['uid'], 'pinned_hide', $midb64, [])))
continue;
-
+
$author = channelx_by_hash($item['author_xchan']);
$owner = channelx_by_hash($item['owner_xchan']);
-
+
$profile_avatar = $author['xchan_photo_m'];
$profile_link = chanlink_hash($item['author_xchan']);
$profile_name = $author['xchan_name'];
@@ -71,7 +71,7 @@ class Pinned {
$isevent = true;
}
}
-
+
$consensus = (intval($item['item_consensus']) ? true : false);
if($consensus) {
$conv_responses['agree'] = [ 'title' => t('Agree','title') ];
@@ -87,7 +87,7 @@ class Pinned {
$verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
$forged = ((! intval($item['item_verified']) && $item['sig']) ? t('Message signature incorrect') : '');
-
+
$shareable = ((local_channel() && \App::$profile_uid == local_channel() && $item['item_private'] != 1) ? true : false);
if ($shareable) {
// This actually turns out not to be possible in some protocol stacks without opening up hundreds of new issues.
@@ -102,9 +102,9 @@ class Pinned {
$is_new = boolval(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0);
$body = prepare_body($item,true);
-
+
$str = [
- 'item_type' => intval($item['item_type']),
+ 'item_type' => intval($item['item_type']),
'body' => $body['html'],
'tags' => $body['tags'],
'categories' => $body['categories'],
@@ -115,7 +115,7 @@ class Pinned {
'id' => $item['id'],
'mids' => json_encode([ $midb64 ]),
'isevent' => $isevent,
- 'attend' => $attend,
+ 'attend' => $attend,
'consensus' => $consensus,
'conlabels' => ($canvote ? $conlabels : []),
'canvote' => $canvote,
@@ -158,55 +158,55 @@ class Pinned {
'modal_dismiss' => t('Close'),
'responses' => $conv_responses
];
-
- $tpl = get_markup_template('pinned_item.tpl');
+
+ $tpl = get_markup_template('pinned_item.tpl');
$ret['html'] .= replace_macros($tpl, $str);
}
return $ret;
}
-
+
/*
* @brief List pinned items depend on type
*
* @param $types
* @return array of pinned items
*
- */
+ */
private function list($types) {
if(empty($types) || (! is_array($types)))
return [];
-
+
$item_types = array_intersect($this->allowed_types, $types);
if(empty($item_types))
return [];
-
+
$mids_list = [];
-
+
foreach($item_types as $type) {
-
+
$mids = get_pconfig($this->uid, 'pinned', $type, []);
foreach($mids as $mid) {
- if(! empty($mid) && strpos($mid,'b64.') === 0)
- $mids_list[] = @base64url_decode(substr($mid,4));
+ if(!empty($mid))
+ $mids_list[] = unpack_link_id($mid);
}
}
if(empty($mids_list))
return [];
-
+
$r = q("SELECT * FROM item WHERE mid IN ( '%s' ) AND uid = %d AND id = parent AND item_private = 0 ORDER BY created DESC",
dbesc(implode(",", $mids_list)),
intval($this->uid)
);
if($r)
return $r;
-
+
return [];
}
-
+
/*
* @brief List activities on item
*
@@ -214,7 +214,7 @@ class Pinned {
* @param array $conv_responses
* @return array
*
- */
+ */
private function activity($item, &$conv_responses) {
foreach(array_keys($conv_responses) as $verb) {
@@ -256,23 +256,23 @@ class Pinned {
unset($conv_responses[$verb]);
continue;
}
-
+
$conv_responses[$verb]['count'] = count($r);
$conv_responses[$verb]['button'] = get_response_button_text($verb, $conv_responses[$verb]['count']);
-
+
foreach($r as $rr) {
-
+
$author = q("SELECT * FROM xchan WHERE xchan_hash = '%s' LIMIT 1",
dbesc($rr['author_xchan'])
);
$name = (($author && $author[0]['xchan_name']) ? $author[0]['xchan_name'] : t('Unknown'));
$conv_responses[$verb]['list'][] = (($rr['author_xchan'] && $author && $author[0]['xchan_photo_s']) ?
- '<a class="dropdown-item" href="' . chanlink_hash($rr['author_xchan']) . '">' . '<img class="menu-img-1" src="' . zid($author[0]['xchan_photo_s']) . '" alt="' . urlencode($name) . '" /> ' . $name . '</a>' :
+ '<a class="dropdown-item" href="' . chanlink_hash($rr['author_xchan']) . '">' . '<img class="menu-img-1" src="' . zid($author[0]['xchan_photo_s']) . '" alt="' . urlencode($name) . '" /> ' . $name . '</a>' :
'<a class="dropdown-item" href="#" class="disabled">' . $name . '</a>'
);
}
}
-
+
$conv_responses['count'] = count($conv_responses);
}
}