aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2024-03-22 08:37:29 +0000
committerMario <mario@mariovavti.com>2024-03-22 08:37:29 +0000
commit1aeb05628b6a2a069c46980efbe628362c9e3e74 (patch)
treee9aed15d0cd74e0c23dcb05c7be8fe9541efdf36 /include
parent5b7387459cf4de8f7354d81cb0392c4225714d94 (diff)
parentb464fae3bf22585888c5f3def8eded76fd48ed16 (diff)
downloadvolse-hubzilla-9.0.tar.gz
volse-hubzilla-9.0.tar.bz2
volse-hubzilla-9.0.zip
Merge branch '9.0RC'9.0
Diffstat (limited to 'include')
-rw-r--r--include/activities.php126
-rw-r--r--include/api_zot.php2
-rw-r--r--include/attach.php167
-rw-r--r--include/bbcode.php828
-rw-r--r--include/channel.php16
-rw-r--r--include/contact_widgets.php2
-rw-r--r--include/conversation.php325
-rw-r--r--include/dba/dba_transaction.php64
-rw-r--r--include/event.php13
-rw-r--r--include/feedutils.php40
-rw-r--r--include/html2bbcode.php90
-rw-r--r--include/html2plain.php5
-rw-r--r--include/import.php6
-rw-r--r--include/items.php205
-rw-r--r--include/markdown.php23
-rw-r--r--include/network.php55
-rw-r--r--include/oembed.php11
-rw-r--r--include/photo/photo_driver.php9
-rw-r--r--include/photos.php6
-rw-r--r--include/plugin.php32
-rw-r--r--include/sharedwithme.php32
-rw-r--r--include/taxonomy.php4
-rw-r--r--include/text.php270
-rw-r--r--include/xchan.php2
24 files changed, 983 insertions, 1350 deletions
diff --git a/include/activities.php b/include/activities.php
index 68c995338..c06a8f6c4 100644
--- a/include/activities.php
+++ b/include/activities.php
@@ -1,95 +1,83 @@
<?php /** @file */
-function profile_activity($changed, $value) {
+use Zotlabs\Lib\Activity;
+use Zotlabs\Daemon\Master;
- if(! local_channel() || ! is_array($changed) || ! count($changed))
- return;
+function profile_activity($changed, $value) {
- if(! get_pconfig(local_channel(),'system','post_profilechange'))
+ if (!local_channel() || !is_array($changed) || !count($changed)) {
return;
+ }
- require_once('include/items.php');
-
- $self = App::get_channel();
-
- if(! count($self))
+ if (!get_pconfig(local_channel(), 'system', 'post_profilechange')) {
return;
+ }
- $arr = array();
- $arr['uuid'] = item_message_id();
- $arr['mid'] = $arr['parent_mid'] = z_root() . '/item/' . $arr['uuid'];
- $arr['uid'] = local_channel();
- $arr['aid'] = $self['channel_account_id'];
- $arr['owner_xchan'] = $arr['author_xchan'] = $self['xchan_hash'];
-
- $arr['item_wall'] = 1;
- $arr['item_origin'] = 1;
- $arr['item_thread_top'] = 1;
- $arr['verb'] = ACTIVITY_UPDATE;
- $arr['obj_type'] = ACTIVITY_OBJ_PROFILE;
+ $channel = App::get_channel();
- $arr['plink'] = z_root() . '/channel/' . $self['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
-
- $A = '[url=' . z_root() . '/channel/' . $self['channel_address'] . ']' . $self['channel_name'] . '[/url]';
+ $arr['verb'] = 'Update';
+ $arr['obj_type'] = 'Profile';
+ $channel_link = '[url=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $channel['channel_name'] . '[/url]';
$changes = '';
$t = count($changed);
$z = 0;
- foreach($changed as $ch) {
- if(strlen($changes)) {
- if ($z == ($t - 1))
+ $photo = false;
+ foreach ($changed as $ch) {
+ if (strlen($changes)) {
+ if ($z == ($t - 1)) {
$changes .= t(' and ');
- else
- $changes .= ', ';
+ } else {
+ $changes .= t(', ');
+ }
+ }
+
+ if (in_array($ch, [t('Profile Photo'), t('Cover Photo')])) {
+ $photo = true;
+ $photo_size = (($ch === t('Profile Photo')) ? 4 : 8);
}
- $z ++;
+
+ $z++;
$changes .= $ch;
}
- $prof = '[url=' . z_root() . '/profile/' . $self['channel_address'] . ']' . t('public profile') . '[/url]';
+ $profile_link = '[url=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . t('public profile') . '[/url]';
- if($t == 1 && strlen($value)) {
+ if ($t == 1 && strlen($value)) {
// if it's a url, the HTML quotes will mess it up, so link it and don't try and zidify it because we don't know what it points to.
- $value = preg_replace_callback("/([^\]\='".'"'."]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ismu", 'red_zrl_callback', $value);
+ $value = preg_replace_callback("/([^='" . '"' . "]|^|#\^)(https?:\/\/[a-zA-Z0-9\pL:\/\-?&;.=@_~#%\$!+,]+)/ismu", 'red_zrl_callback', $value);
// take out the bookmark indicator
- if(substr($value,0,2) === '#^')
- $value = str_replace('#^','',$value);
+ if (str_starts_with($value, '#^')) {
+ $value = str_replace('#^', '', $value);
+ }
- $message = sprintf( t('%1$s changed %2$s to &ldquo;%3$s&rdquo;'), $A, $changes, $value);
- $message .= "\n\n" . sprintf( t('Visit %1$s\'s %2$s'), $A, $prof);
- }
- else
- $message = sprintf( t('%1$s has an updated %2$s, changing %3$s.'), $A, $prof, $changes);
-
-
- $arr['body'] = $message;
-
- $links = array();
- $links[] = array('rel' => 'alternate', 'type' => 'text/html',
- 'href' => z_root() . '/profile/' . $self['channel_address']);
- $links[] = array('rel' => 'photo', 'type' => $self['xchan_photo_mimetype'],
- 'href' => $self['xchan_photo_l']);
-
- $arr['object'] = json_encode(array(
- 'type' => ACTIVITY_OBJ_PROFILE,
- 'title' => $self['channel_name'],
- 'id' => $self['xchan_url'] . '/' . $self['xchan_hash'],
- 'link' => $links
- ));
-
-
- $arr['allow_cid'] = $self['channel_allow_cid'];
- $arr['allow_gid'] = $self['channel_allow_gid'];
- $arr['deny_cid'] = $self['channel_deny_cid'];
- $arr['deny_gid'] = $self['channel_deny_gid'];
-
- $res = item_store($arr);
- $i = $res['item_id'];
-
- if($i) {
- // FIXME - limit delivery in notifier.php to those specificed in the perms argument
- Zotlabs\Daemon\Master::Summon(array('Notifier','activity', $i, 'PERMS_R_PROFILE'));
+ if ($photo) {
+ $value = "\n\n" . '[zmg=' . z_root() . '/photo/' . $value . '-' . $photo_size . ']' . $ch . ' ' . $channel['xchan_name'] . '[/zmg]';
+ }
+ else {
+ $value = '"' . $value . '"';
+ }
+
+ $message = sprintf(t('%1$s %2$s has been updated to %3$s.'), $channel_link . '\'s' . (($photo) ? '' : ' ' . $profile_link), strtolower($changes), $value);
+
+ } else {
+ $message = sprintf(t('%1$s updated the %2$s. Changed %3$s.'), $channel_link, $profile_link, strtolower($changes));
}
+ $arr['body'] = $message;
+
+ $arr['obj'] = [
+ 'type' => 'Profile',
+ 'content' => bbcode($message),
+ 'source' => [
+ 'content' => $message,
+ 'mediaType' => 'text/bbcode'
+ ],
+ 'describes' => Activity::encode_person($channel),
+ 'url' => z_root() . '/profile/' . $channel['channel_address']
+ ];
+
+ post_activity_item($arr);
+
}
diff --git a/include/api_zot.php b/include/api_zot.php
index 7a217854f..22692b962 100644
--- a/include/api_zot.php
+++ b/include/api_zot.php
@@ -561,7 +561,7 @@
$mod = new Zotlabs\Module\Wall_attach();
$media = $mod->post();
if($media)
- $_REQUEST['body'] .= "\n\n" . $media;
+ $_REQUEST['body'] = $media . "\n\n" . $_REQUEST['body'];
}
$mod = new Zotlabs\Module\Item();
diff --git a/include/attach.php b/include/attach.php
index 9baebe2a0..e5a2900b3 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -1854,169 +1854,6 @@ function pipe_streams($in, $out, $bufsize = 16384) {
return $size;
}
-/**
- * @brief Activity for files.
- *
- * @param int $channel_id
- * @param array $object
- * @param string $allow_cid
- * @param string $allow_gid
- * @param string $deny_cid
- * @param string $deny_gid
- * @param string $verb
- * @param boolean $notify
- */
-/*
-function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $verb, $notify) {
-
- require_once('include/items.php');
-
- $poster = App::get_observer();
-
- //if we got no object something went wrong
- if(!$object)
- return;
-
- //turn strings into arrays
- $arr_allow_cid = expand_acl($allow_cid);
- $arr_allow_gid = expand_acl($allow_gid);
- $arr_deny_cid = expand_acl($deny_cid);
- $arr_deny_gid = expand_acl($deny_gid);
-
- //filter out receivers which do not have permission to view filestorage
- $arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage');
-
- $is_dir = (intval($object['is_dir']) ? true : false);
-
- //do not send activity for folders for now
- if($is_dir)
- return;
-
- //check for recursive perms if we are in a folder
- if($object['folder']) {
-
- $folder_hash = $object['folder'];
-
- $r_perms = attach_recursive_perms($arr_allow_cid, $arr_allow_gid, $arr_deny_cid, $arr_deny_gid, $folder_hash);
-
- if($r_perms === false) //nobody has recursive perms - nobody must be notified
- return;
-
- //split up returned perms
- $arr_allow_cid = $r_perms['allow_cid'];
- $arr_allow_gid = $r_perms['allow_gid'];
- $arr_deny_cid = $r_perms['deny_cid'];
- $arr_deny_gid = $r_perms['deny_gid'];
-
- //filter out receivers which do not have permission to view filestorage
- $arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage');
- }
-
- $uuid = item_message_id();
- $mid = z_root() . '/item/' . $uuid;
-
- $objtype = 'ACTIVITY_OBJ_FILE';
-
- $arr = array();
- $arr['aid'] = get_account_id();
- $arr['uid'] = $channel_id;
- $arr['uuid'] = $uuid;
- $arr['item_wall'] = 1;
- $arr['item_origin'] = 1;
- $arr['item_unseen'] = 1;
- $arr['author_xchan'] = $poster['xchan_hash'];
- $arr['owner_xchan'] = $poster['xchan_hash'];
- $arr['title'] = '';
- $arr['item_notshown'] = 1;
- $arr['obj_type'] = $objtype;
- $arr['resource_id'] = $object['hash'];
- $arr['resource_type'] = 'attach';
-
- $private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0);
-
- $jsonobject = json_encode($object);
-
- //check if item for this object exists
- $y = q("SELECT mid FROM item WHERE verb = '%s' AND obj_type = '%s' AND resource_id = '%s' AND uid = %d LIMIT 1",
- dbesc(ACTIVITY_POST),
- dbesc($objtype),
- dbesc($object['hash']),
- intval(local_channel())
- );
-
- if($y) {
- $update = true;
- $object['d_mid'] = $y[0]['mid']; //attach mid of the old object
- $u_jsonobject = json_encode($object);
-
- //we have got the relevant info - delete the old item before we create the new one
- q("DELETE FROM item WHERE obj_type = '%s' AND verb = '%s' AND mid = '%s'",
- dbesc(ACTIVITY_OBJ_FILE),
- dbesc(ACTIVITY_POST),
- dbesc($y[0]['mid'])
- );
-
- }
-
- //send update activity and create a new one
- if($update && $verb == 'post' ) {
- //updates should be sent to everybody with recursive perms and all eventual former allowed members ($object['allow_cid'] etc.).
- $u_arr_allow_cid = array_unique(array_merge($arr_allow_cid, expand_acl($object['allow_cid'])));
- $u_arr_allow_gid = array_unique(array_merge($arr_allow_gid, expand_acl($object['allow_gid'])));
- $u_arr_deny_cid = array_unique(array_merge($arr_deny_cid, expand_acl($object['deny_cid'])));
- $u_arr_deny_gid = array_unique(array_merge($arr_deny_gid, expand_acl($object['deny_gid'])));
-
- $private = (($u_arr_allow_cid[0] || $u_arr_allow_gid[0] || $u_arr_deny_cid[0] || $u_arr_deny_gid[0]) ? 1 : 0);
-
- $uuid = item_message_id();
- $u_mid = z_root() . '/item/' . $uuid;
-
- $arr['uuid'] = $uuid;
- $arr['mid'] = $u_mid;
- $arr['parent_mid'] = $u_mid;
- $arr['allow_cid'] = perms2str($u_arr_allow_cid);
- $arr['allow_gid'] = perms2str($u_arr_allow_gid);
- $arr['deny_cid'] = perms2str($u_arr_deny_cid);
- $arr['deny_gid'] = perms2str($u_arr_deny_gid);
- $arr['item_private'] = $private;
- $arr['verb'] = ACTIVITY_UPDATE;
- $arr['obj'] = $u_jsonobject;
- $arr['body'] = '';
-
- post_activity_item($arr);
-
- $update = false;
- }
-
- //don't create new activity if notify was not enabled
- if(! $notify) {
- return;
- }
-
- //don't create new activity if we have an update request but there is no item to update
- //this can e.g. happen when deleting images
- if(! $y && $verb == 'update') {
- return;
- }
-
- $arr['mid'] = $mid;
- $arr['parent_mid'] = $mid;
- $arr['allow_cid'] = perms2str($arr_allow_cid);
- $arr['allow_gid'] = perms2str($arr_allow_gid);
- $arr['deny_cid'] = perms2str($arr_deny_cid);
- $arr['deny_gid'] = perms2str($arr_deny_gid);
- $arr['item_private'] = $private;
- $arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST);
- $arr['obj'] = (($update) ? $u_jsonobject : $jsonobject);
- $arr['body'] = '';
-
- post_activity_item($arr);
-
- return;
-}
-*/
-
-
function attach_store_item($channel, $observer, $file) {
@@ -2127,7 +1964,7 @@ function attach_store_item($channel, $observer, $file) {
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['item_private'] = (($file['allow_cid'] || $file['allow_gid'] || $file['deny_cid'] || $file['deny_gid']) ? 1 : 0);
- $arr['verb'] = ACTIVITY_CREATE;
+ $arr['verb'] = 'Create';
$arr['obj_type'] = $type;
$arr['title'] = $file['filename'];
@@ -2773,7 +2610,7 @@ function attach_move($channel_id, $resource_id, $new_folder_hash, $newname = '',
intval($channel_id)
);
- q("update photo set content = CASE imgscale WHEN 0 THEN '%s' ELSE CONCAT('%s', '-', imgscale) END where resource_id = '%s' and uid = %d and os_storage = 1",
+ q("update photo set content = CASE imgscale WHEN 0 THEN %s ELSE CONCAT(%s, '-', imgscale) END where resource_id = '%s' and uid = %d and os_storage = 1",
dbescbin($newstorepath),
dbescbin($newstorepath),
dbesc($resource_id),
diff --git a/include/bbcode.php b/include/bbcode.php
index e0a0fe9a1..79cb82c0b 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -246,42 +246,47 @@ function bb_replace_images($body, $images) {
function bb_parse_crypt($match) {
$matches = [];
- $attributes = $match[1];
+ $hint = '';
+ $algorithm = '';
+ $payload = $match[1];
- $algorithm = "";
+ if (isset($match[2])) {
+ // backwards compatibility
- preg_match("/alg='(.*?)'/ism", $attributes, $matches);
- if ($matches[1] != "")
- $algorithm = $matches[1];
+ $attributes = $match[1];
+ $payload = $match[2];
- preg_match("/alg=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
- if ($matches[1] != "")
- $algorithm = $matches[1];
+ preg_match("/alg='(.*?)'/ism", $attributes, $matches);
+ $algorithm = $matches[1] ?? '';
- $hint = "";
+ if (!$algorithm) {
+ preg_match("/alg=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
+ $algorithm = $matches[1] ?? '';
+ }
- preg_match("/hint='(.*?)'/ism", $attributes, $matches);
- if ($matches[1] != "")
- $hint = $matches[1];
- preg_match("/hint=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
- if ($matches[1] != "")
- $hint = $matches[1];
+ preg_match("/hint='(.*?)'/ism", $attributes, $matches);
+ $hint = $matches[1] ?? '';
+
+ if (!$hint) {
+ preg_match("/hint=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
+ $hint = $matches[1] ?? '';
+ }
+ }
- $x = random_string();
+ $x = random_string(32);
- $f = 'hz_decrypt';
+ $onclick = 'onclick="sodium_decrypt(\'' . $payload . '\',\'#' . $x . '\');"';
- //legacy cryptojs support
- if(plugin_is_installed('cryptojs')) {
- $f = ((in_array($algorithm, ['AES-128-CCM', 'rot13', 'triple-rot13'])) ? 'hz_decrypt' : 'red_decrypt');
+ if (in_array($algorithm, ['AES-128-CCM', 'rot13', 'triple-rot13'])) {
+ // backwards compatibility
+ $onclick = 'onclick="hz_decrypt(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $payload . '\',\'#' . $x . '\');"';
}
- $onclick = 'onclick="' . $f . '(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $match[2] . '\',\'#' . $x . '\');"';
$label = t('Encrypted content');
- $Text = '<br /><div id="' . $x . '"><img class="cursor-pointer" src="' . z_root() . '/images/lock_icon.svg" ' . $onclick . ' alt="' . $label . '" title="' . $label . '" /></div><br />';
+ $text = '<div id="' . $x . '" class="encrypted-content"><img class="cursor-pointer" src="' . z_root() . '/images/lock_icon.svg" ' . $onclick . ' alt="' . $label . '" title="' . $label . '" /></div>';
- return $Text;
+ return $text;
}
/**
@@ -292,20 +297,20 @@ function bb_parse_crypt($match) {
*/
function bb_parse_b64_crypt($match) {
- if(empty($match[2]))
+ if(empty($match[1])) {
return;
+ }
- $r .= '<code>';
- $r .= '----- ENCRYPTED CONTENT -----' . '<br>';
- $r .= $match[2] . '<br>';
- $r .= '----- END ENCRYPTED CONTENT -----';
- $r .= '</code>';
+ $r = '-----BEGIN ENCRYPTED MESSAGE-----' . "\n";
+ $r .= $match[1] . "\n";
+ $r .= '-----END ENCRYPTED MESSAGE-----' . "\n";
+
+ $r = '<code>' . str_replace("\n", '<br>', wordwrap($r, 75, "\n", true)) . '</code>';
return $r;
}
-
function bb_parse_app($match) {
$app = Zotlabs\Lib\Apps::app_decode($match[1]);
@@ -809,36 +814,56 @@ function oblanguage_necallback($matches) {
return '';
}
-function bb_observer($Text) {
-
- $observer = App::get_observer();
+/**
+ * Process [observer] tags in the source text.
+ *
+ * @param string $text The source BBCode text.
+ * @param ?array $observer Array containing the observer we render for, or
+ * null if none.
+ *
+ * @return A string where the [observer] tags have been processed.
+ */
+function bb_observer(string $text, ?array $observer): string {
- if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
+ if ((strpos($text,'[/observer]') !== false) || (strpos($text,'[/rpost]') !== false)) {
+ $text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $text);
+ $text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $text);
if ($observer) {
- $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text);
+ $text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $text);
+ $text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $text);
+ $text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $text);
} else {
- $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text);
+ $text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $text);
+ $text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $text);
+ $text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $text);
}
}
- $channel = App::get_channel();
+ return $text;
+}
+
+/**
+ * Process [channel] tags in the source text.
+ *
+ * @param string $text The source BBCode text.
+ * @param ?array $channel Array containing the channel we render for, or
+ * null if none.
+ *
+ * @return A string where the [channel] tags have been processed.
+ */
+function bb_channel(string $text, ?array $channel): string {
- if (strpos($Text,'[/channel]') !== false) {
+ if (strpos($text,'[/channel]') !== false) {
if ($channel) {
- $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text);
- $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text);
+ $text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $text);
+ $text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $text);
} else {
- $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text);
- $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text);
+ $text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $text);
+ $text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $text);
}
}
-
- return $Text;
+ return $text;
}
function bb_imgoptions($match) {
@@ -849,11 +874,13 @@ function bb_imgoptions($match) {
// [img|zmg=wwwxhhh float=left|right alt=alt text]url[/img|zmg]
$local_match = null;
- $width = 0;
- $float = false;
- $alt = false;
-
- $style = EMPTY_STR;
+ $width = EMPTY_STR;
+ $height = EMPTY_STR;
+ $float = EMPTY_STR;
+ $alt = EMPTY_STR;
+ $title = EMPTY_STR;
+ $style = EMPTY_STR;
+ $class = EMPTY_STR;
$attributes = $match[3];
@@ -862,6 +889,16 @@ function bb_imgoptions($match) {
$alt = $matches[1];
}
+ $x = preg_match("/title=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
+ if ($x) {
+ $title = $matches[1];
+ }
+
+ $x = preg_match("/title='(.*?)'/ism", $attributes, $matches);
+ if ($x) {
+ $title = $matches[1];
+ }
+
$x = preg_match("/alt=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
if ($x) {
$alt = $matches[1];
@@ -887,16 +924,27 @@ function bb_imgoptions($match) {
$height = $matches[1];
}
+ $x = preg_match("/class='(.*?)'/ism", $attributes, $matches);
+ if ($x) {
+ $class = $matches[1];
+ }
+
+ $x = preg_match("/class=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
+ if ($x) {
+ $class = $matches[1];
+ }
+
+/* should probably sanitize css somehow
$x = preg_match("/style='(.*?)'/ism", $attributes, $matches);
if ($x) {
- $style = $matches[1];
+ $style = $matches[1] . ' ';
}
$x = preg_match("/style=\&quot\;(.*?)\&quot\;/ism", $attributes, $matches);
if ($x) {
- $style = $matches[1];
+ $style = $matches[1] . ' ';
}
-
+*/
// legacy img options
if ($match[2] === '=') {
@@ -912,6 +960,7 @@ function bb_imgoptions($match) {
$float = 'left';
$match[3] = substr($match[3],$n + 10);
}
+
if ($n = strpos($match[3],'float=right') !== false) {
$float = 'right';
$match[3] = substr($match[3],$n + 11);
@@ -927,18 +976,25 @@ function bb_imgoptions($match) {
$output = '<img ' . (($match[1] === 'z') ? 'class="zrl" loading="eager"' : '') . ' ';
if ($width) {
- $style .= 'width: 100%; max-width: ' . $width . 'px; ';
+ $style .= 'width: ' . intval($width) . 'px; ';
}
- else {
- $style .= 'max-width: 100%; ';
+
+ if ($height) {
+ $style .= 'height: ' . intval($height) . 'px; ';
}
+
if ($float) {
$style .= 'float: ' . $float . '; ';
}
- $output .= (($style) ? 'style="' . $style . '" ' : '') . 'alt="' . htmlentities(($alt) ? $alt : t('Image/photo'),ENT_COMPAT,'UTF-8') . '" ';
+ $style .= 'max-width: 100%;';
+
+ $output .= 'style="' . $style . '" ';
+ $output .= 'alt="' . htmlentities(($alt ? $alt : t('Image/photo')), ENT_COMPAT, 'UTF-8') . '" ';
+ $output .= 'title="' . htmlentities($title, ENT_COMPAT, 'UTF-8') . '" ';
+ $output .= 'class="' . htmlentities($class, ENT_COMPAT, 'UTF-8') . '" ';
- $output .= 'src="' . $match[4] . '" >';
+ $output .= 'src="' . $match[4] . '" />';
return $output;
@@ -957,7 +1013,7 @@ function bb_code_unprotect_sub($match) {
}
function bb_code($match) {
- if(strpos($match[0], PHP_EOL))
+ if(strpos($match[0], PHP_EOL) !== false)
return '<pre><code>' . bb_code_protect(trim($match[1])) . '</code></pre>';
else
return '<code class="inline-code">' . bb_code_protect(trim($match[1])) . '</code>';
@@ -998,6 +1054,15 @@ function bb_fixtable_lf($match) {
}
+function bb_fix_lf($match) {
+ // remove extraneous whitespace between element tags since newlines will all
+ // be converted to '<br />' and turn your neatly crafted tables into a whole lot of
+ // empty space.
+
+ $new_content = str_replace(["\n\r", "\n", "\r"], '', $match[1]);
+ return str_replace($match[1], $new_content, $match[0]);
+}
+
function bbtopoll($s) {
$pl = [];
@@ -1095,145 +1160,140 @@ function parseIdentityAwareHTML($Text) {
}
-function bbcode($Text, $options = []) {
+/**
+ * Converts Hubzilla flavoured BBCode to HTML.
+ *
+ * @param string $text BBCode formatted text
+ *
+ * @param array $options Optional arguments to controll how the conversion
+ * is to be done.
+ * - `tryoembed` (`true`) - Whether we should try to generate link previews/oembeds.
+ * - `cache` (`false`) - Avoids some processing if true, unsure about the significancd of it for now.
+ * - `newwin` (`true`) - Wether links should open in a new window (`target="_blank"`)
+ *
+ * @return A string containing the resulting HTML code.
+ */
+function bbcode($text, $options = []) {
+
+ if (!$text) {
+ return EMPTY_STR;
+ }
if(! is_array($options)) {
$options = [];
}
- $preserve_nl = ((array_key_exists('preserve_nl',$options)) ? $options['preserve_nl'] : false);
$tryoembed = ((array_key_exists('tryoembed',$options)) ? $options['tryoembed'] : true);
$cache = ((array_key_exists('cache',$options)) ? $options['cache'] : false);
$newwin = ((array_key_exists('newwin',$options)) ? $options['newwin'] : true);
$target = (($newwin) ? ' target="_blank" ' : '');
- call_hooks('bbcode_filter', $Text);
+ /**
+ * @hooks bbcode_filter
+ * * _string_ **bbcode** - The raw bbcode input before converting it to HTML.
+ */
+ call_hooks('bbcode_filter', $text);
if(isset($options['drop_media'])) {
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace('/\[img(.*?)\[\/(img)\]/ism', '', $Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace('/\[img(.*?)\[\/(img)\]/ism', '', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace('/\[audio(.*?)\[\/(audio)\]/ism', '', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace('/\[audio(.*?)\[\/(audio)\]/ism', '', $text);
}
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace('/\[video(.*?)\[\/(video)\]/ism', '', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace('/\[video(.*?)\[\/(video)\]/ism', '', $text);
}
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace('/\[zmg(.*?)\[\/(zmg)\]/ism', '', $Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace('/\[zmg(.*?)\[\/(zmg)\]/ism', '', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace('/\[zaudio(.*?)\[\/(zaudio)\]/ism', '', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace('/\[zaudio(.*?)\[\/(zaudio)\]/ism', '', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace('/\[zvideo(.*?)\[\/(zvideo)\]/ism', '', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace('/\[zvideo(.*?)\[\/(zvideo)\]/ism', '', $text);
}
}
-
-
- $Text = bb_format_attachdata($Text);
+ $text = bb_format_attachdata($text);
// If we find any event code, turn it into an event.
// After we're finished processing the bbcode we'll
// replace all of the event code with a reformatted version.
- $ev = bbtoevent($Text);
+ $ev = bbtoevent($text);
// and the same with polls
- $pl = bbtopoll($Text);
+ $pl = bbtopoll($text);
- // process [observer] tags before we do anything else because we might
- // be stripping away stuff that then doesn't need to be worked on anymore
-
- if($cache)
- $observer = false;
- else
+ if($cache) {
+ $observer = null;
+ $channel = null;
+ } else {
$observer = App::get_observer();
-
- if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
- $Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $Text);
- $Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $Text);
-
- if ($observer) {
- $Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace_callback("/\[rpost(=(.*?))?\](.*?)\[\/rpost\]/ism", 'rpost_callback', $Text);
- } else {
- $Text = preg_replace("/\[observer\=1\].*?\[\/observer\]/ism", '', $Text);
- $Text = preg_replace("/\[observer\=0\](.*?)\[\/observer\]/ism", '$1', $Text);
- $Text = preg_replace("/\[rpost(=.*?)?\](.*?)\[\/rpost\]/ism", '', $Text);
- }
+ $channel = App::get_channel();
}
- if($cache)
- $channel = false;
- else
- $channel = App::get_channel();
+ // process [observer] and [channel] tags before we do anything else because
+ // we might be stripping away stuff that then doesn't need to be worked on
+ // anymore
- if (strpos($Text,'[/channel]') !== false) {
- if ($channel) {
- $Text = preg_replace("/\[channel\=1\](.*?)\[\/channel\]/ism", '$1', $Text);
- $Text = preg_replace("/\[channel\=0\].*?\[\/channel\]/ism", '', $Text);
- } else {
- $Text = preg_replace("/\[channel\=1\].*?\[\/channel\]/ism", '', $Text);
- $Text = preg_replace("/\[channel\=0\](.*?)\[\/channel\]/ism", '$1', $Text);
- }
- }
+ $text = bb_observer($text, $observer);
+ $text = bb_channel($text, $channel);
- $x = bb_extract_images($Text);
- $Text = $x['body'];
+ $x = bb_extract_images($text);
+ $text = $x['body'];
$saved_images = $x['images'];
- $Text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$Text);
+ $text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$text);
// Replace any html brackets with HTML Entities to prevent executing HTML or script
// Don't use strip_tags here because it breaks [url] search by replacing & with amp
- $Text = str_replace("<", "&lt;", $Text);
- $Text = str_replace(">", "&gt;", $Text);
- $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$Text);
- $Text = str_replace(array("\t", " "), array("&nbsp;&nbsp;&nbsp;&nbsp;", "&nbsp;&nbsp;"), $Text);
+ $text = str_replace("<", "&lt;", $text);
+ $text = str_replace(">", "&gt;", $text);
+
+ $text = str_replace(array("\t", " "), array("&nbsp;&nbsp;&nbsp;&nbsp;", "&nbsp;&nbsp;"), $text);
// Check for [code] text here, before the linefeeds are messed with.
// The highlighter will unescape and re-escape the content.
- if (strpos($Text,'[code=') !== false) {
- $Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text);
+ if (strpos($text,'[code=') !== false) {
+ $text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $text);
}
// Check for [code] text
- if (strpos($Text,'[code]') !== false) {
- $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text);
+ if (strpos($text,'[code]') !== false) {
+ $text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $text);
}
// Check for [code options] text
- if (strpos($Text,'[code ') !== false) {
- $Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $Text);
+ if (strpos($text,'[code ') !== false) {
+ $text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $text);
}
// Hide all [noparse] contained bbtags by spacefying them
- if (strpos($Text,'[noparse]') !== false) {
- $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[noparse]') !== false) {
+ $text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[nobb]') !== false) {
- $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[nobb]') !== false) {
+ $text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[pre]') !== false) {
- $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[pre]') !== false) {
+ $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[summary]') !== false) {
- $Text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_spacefy',$Text);
+ if (strpos($text,'[summary]') !== false) {
+ $text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_spacefy',$text);
}
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace_callback('/\[img(.*?)\[\/(img)\]/ism','\red_escape_codeblock',$Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace_callback('/\[img(.*?)\[\/(img)\]/ism','\red_escape_codeblock',$text);
}
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace_callback('/\[zmg(.*?)\[\/(zmg)\]/ism','\red_escape_codeblock',$Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace_callback('/\[zmg(.*?)\[\/(zmg)\]/ism','\red_escape_codeblock',$text);
}
// Set up the parameters for a URL search string
@@ -1247,19 +1307,19 @@ function bbcode($Text, $options = []) {
$s2 = '</span>';
$obsBaseURL = $observer['xchan_connurl'];
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
- $Text = str_replace('[observer.baseurl]', $obsBaseURL, $Text);
- $Text = str_replace('[observer.url]',$observer['xchan_url'], $Text);
- $Text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $Text);
- $Text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $Text);
- $Text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $Text);
- $Text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $Text);
+ $text = str_replace('[observer.baseurl]', $obsBaseURL, $text);
+ $text = str_replace('[observer.url]',$observer['xchan_url'], $text);
+ $text = str_replace('[observer.name]',$s1 . $observer['xchan_name'] . $s2, $text);
+ $text = str_replace('[observer.address]',$s1 . $observer['xchan_addr'] . $s2, $text);
+ $text = str_replace('[observer.webname]', substr($observer['xchan_addr'],0,strpos($observer['xchan_addr'],'@')), $text);
+ $text = str_replace('[observer.photo]',$s1 . '[zmg]'.$observer['xchan_photo_l'].'[/zmg]' . $s2, $text);
} else {
- $Text = str_replace('[observer.baseurl]', '', $Text);
- $Text = str_replace('[observer.url]','', $Text);
- $Text = str_replace('[observer.name]','', $Text);
- $Text = str_replace('[observer.address]','', $Text);
- $Text = str_replace('[observer.webname]','',$Text);
- $Text = str_replace('[observer.photo]','', $Text);
+ $text = str_replace('[observer.baseurl]', '', $text);
+ $text = str_replace('[observer.url]','', $text);
+ $text = str_replace('[observer.name]','', $text);
+ $text = str_replace('[observer.address]','', $text);
+ $text = str_replace('[observer.webname]','',$text);
+ $text = str_replace('[observer.photo]','', $text);
}
@@ -1268,257 +1328,283 @@ function bbcode($Text, $options = []) {
$urlchars = '[a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]';
- if (strpos($Text,'http') !== false) {
+ if (strpos($text,'http') !== false) {
if($tryoembed) {
- $Text = preg_replace_callback("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", 'tryoembed', $Text);
+ $text = preg_replace_callback("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", 'tryoembed', $text);
}
// Is this still desired?
// We already turn naked URLs into links during creation time cleanup_bbcode()
- $Text = preg_replace("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $Text);
+ $text = preg_replace("/([^\]\='".'"'."\;\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $text);
}
$count = 0;
- while (strpos($Text,'[/share]') !== false && $count < 10) {
- $Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $Text);
+ while (strpos($text,'[/share]') !== false && $count < 10) {
+ $text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_ShareAttributes', $text);
$count ++;
}
if($tryoembed) {
- if (strpos($Text,'[/url]') !== false) {
- $Text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/url]') !== false) {
+ $text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $text);
}
}
- if (strpos($Text,'[/url]') !== false) {
- $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
- $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
+ if (strpos($text,'[/url]') !== false) {
+ $text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
+ $text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
}
- if (strpos($Text,'[/zrl]') !== false) {
- $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
- $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
+ if (strpos($text,'[/zrl]') !== false) {
+ $text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
+ $text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
}
// Perform MAIL Search
- if (strpos($Text,'[/mail]') !== false) {
- $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
- $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
+ if (strpos($text,'[/mail]') !== false) {
+ $text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
+ $text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $text);
}
// leave open the posibility of [map=something]
// this is replaced in prepare_body() which has knowledge of the item location
if ($cache) {
- $Text = str_replace([ '[map]','[/map]' ], [ '','' ], $Text);
- $Text = preg_replace('/\[map=(.*?)\]/ism','$1',$Text);
+ $text = str_replace([ '[map]','[/map]' ], [ '','' ], $text);
+ $text = preg_replace('/\[map=(.*?)\]/ism','$1',$text);
}
else {
- if (strpos($Text,'[/map]') !== false) {
- $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text);
+ if (strpos($text,'[/map]') !== false) {
+ $text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $text);
}
- if (strpos($Text,'[map=') !== false) {
- $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text);
+ if (strpos($text,'[map=') !== false) {
+ $text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $text);
}
- if (strpos($Text,'[map]') !== false) {
- $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text);
+ if (strpos($text,'[map]') !== false) {
+ $text = preg_replace("/\[map\]/", '<div class="map"></div>', $text);
}
}
// Check for bold text
- if (strpos($Text,'[b]') !== false) {
- $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $Text);
+ if (strpos($text,'[b]') !== false) {
+ $text = preg_replace("(\[b\](.*?)\[\/b\])ism", '<strong>$1</strong>', $text);
}
// Check for Italics text
- if (strpos($Text,'[i]') !== false) {
- $Text = preg_replace("(\[i\](.*?)\[\/i\])ism", '<em>$1</em>', $Text);
+ if (strpos($text,'[i]') !== false) {
+ $text = preg_replace("(\[i\](.*?)\[\/i\])ism", '<em>$1</em>', $text);
}
// Check for Underline text
- if (strpos($Text,'[u]') !== false) {
- $Text = preg_replace("(\[u\](.*?)\[\/u\])ism", '<u>$1</u>', $Text);
+ if (strpos($text,'[u]') !== false) {
+ $text = preg_replace("(\[u\](.*?)\[\/u\])ism", '<u>$1</u>', $text);
}
// Check for strike-through text
- if (strpos($Text,'[s]') !== false) {
- $Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<span style="text-decoration: line-through;">$1</span>', $Text);
+ if (strpos($text,'[s]') !== false) {
+ $text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<span style="text-decoration: line-through;">$1</span>', $text);
}
// Check for over-line text
- if (strpos($Text,'[o]') !== false) {
- $Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span style="text-decoration: overline;">$1</span>', $Text);
+ if (strpos($text,'[o]') !== false) {
+ $text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span style="text-decoration: overline;">$1</span>', $text);
}
- if (strpos($Text,'[sup]') !== false) {
- $Text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '<sup>$1</sup>', $Text);
+ if (strpos($text,'[sup]') !== false) {
+ $text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '<sup>$1</sup>', $text);
}
- if (strpos($Text,'[sub]') !== false) {
- $Text = preg_replace("(\[sub\](.*?)\[\/sub\])ism", '<sub>$1</sub>', $Text);
+ if (strpos($text,'[sub]') !== false) {
+ $text = preg_replace("(\[sub\](.*?)\[\/sub\])ism", '<sub>$1</sub>', $text);
}
// Check for colored text
- if (strpos($Text,'[/color]') !== false) {
- $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "<span style=\"color: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/color]') !== false) {
+ $text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism", "<span style=\"color: $1;\">$2</span>", $text);
}
// @DEPRECATED: Check for colored text (deprecated in favor of mark which is a html5 standard)
- if (strpos($Text,'[/hl]') !== false) {
- $Text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "<span class=\"default-highlight\">$1</span>", $Text);
- $Text = preg_replace("(\[hl=(.*?)\](.*?)\[\/hl\])ism", "<span style=\"background-color: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/hl]') !== false) {
+ $text = preg_replace("(\[hl\](.*?)\[\/hl\])ism", "<span class=\"default-highlight\">$1</span>", $text);
+ $text = preg_replace("(\[hl=(.*?)\](.*?)\[\/hl\])ism", "<span style=\"background-color: $1;\">$2</span>", $text);
}
- if (strpos($Text,'[/mark]') !== false) {
- $Text = preg_replace("(\[mark\](.*?)\[\/mark\])ism", "<mark class=\"mark\">$1</mark>", $Text);
- $Text = preg_replace("(\[mark=(.*?)\](.*?)\[\/mark\])ism", "<mark style=\"background-color: $1;\">$2</mark>", $Text);
+ if (strpos($text,'[/mark]') !== false) {
+ $text = preg_replace("(\[mark\](.*?)\[\/mark\])ism", "<mark class=\"mark\">$1</mark>", $text);
+ $text = preg_replace("(\[mark=(.*?)\](.*?)\[\/mark\])ism", "<mark style=\"background-color: $1;\">$2</mark>", $text);
}
// Check for sized text
// [size=50] --> font-size: 50px (with the unit).
- if (strpos($Text,'[/size]') !== false) {
- $Text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px;\">$2</span>", $Text);
- $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/size]') !== false) {
+ $text = preg_replace("(\[size=(\d*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1px;\">$2</span>", $text);
+ $text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism", "<span style=\"font-size: $1;\">$2</span>", $text);
}
// Check for h1
- if (strpos($Text,'[h1]') !== false) {
- $Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$Text);
- $Text = str_replace('</h1><br />', '</h1>', $Text);
+ if (strpos($text,'[h1]') !== false) {
+ $text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$text);
+ $text = str_replace(["</h1>\r", "</h1>\n"], '</h1>', $text);
}
// Check for h2
- if (strpos($Text,'[h2]') !== false) {
- $Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$Text);
- $Text = str_replace('</h2><br />', '</h2>', $Text);
+ if (strpos($text,'[h2]') !== false) {
+ $text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$text);
+ $text = str_replace(["</h2>\r", "</h2>\n"], '</h2>', $text);
}
// Check for h3
- if (strpos($Text,'[h3]') !== false) {
- $Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$Text);
- $Text = str_replace('</h3><br />', '</h3>', $Text);
+ if (strpos($text,'[h3]') !== false) {
+ $text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$text);
+ $text = str_replace(["</h3>\r", "</h3>\n"], '</h3>', $text);
}
// Check for h4
- if (strpos($Text,'[h4]') !== false) {
- $Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$Text);
- $Text = str_replace('</h4><br />', '</h4>', $Text);
+ if (strpos($text,'[h4]') !== false) {
+ $text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$text);
+ $text = str_replace(["</h4>\r", "</h4>\n"], '</h4>', $text);
}
// Check for h5
- if (strpos($Text,'[h5]') !== false) {
- $Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
- $Text = str_replace('</h5><br />', '</h5>', $Text);
+ if (strpos($text,'[h5]') !== false) {
+ $text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$text);
+ $text = str_replace(["</h5>\r", "</h5>\n"], '</h5>', $text);
}
// Check for h6
- if (strpos($Text,'[h6]') !== false) {
- $Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
- $Text = str_replace('</h6><br />', '</h6>', $Text);
+ if (strpos($text,'[h6]') !== false) {
+ $text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$text);
+ $text = str_replace(["</h6>\r", "</h6>\n"], '</h6>', $text);
}
// Check for table of content without params
- while(strpos($Text,'[toc]') !== false) {
+ while(strpos($text,'[toc]') !== false) {
$toc_id = 'toc-' . random_string(10);
- $Text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc"></ul><script>$(document).ready(function() { let toc_container = $("#' . $toc_id . '").parent().closest("div").attr("id") || ".section-content-wrapper"; $("#' . $toc_id . '").toc({content: "#" + toc_container, headings: "h1,h2,h3,h4"}); });</script>', $Text, 1);
+ $text = preg_replace("/\[toc\]/ism", '<ul id="' . $toc_id . '" class="toc"></ul><script>$(document).ready(function() { let toc_container = $("#' . $toc_id . '").parent().closest("div").attr("id") || ".section-content-wrapper"; $("#' . $toc_id . '").toc({content: "#" + toc_container, headings: "h1,h2,h3,h4"}); });</script>', $text, 1);
}
// Check for table of content with params
- while(strpos($Text,'[toc') !== false) {
+ while(strpos($text,'[toc') !== false) {
$toc_id = 'toc-' . random_string(10);
- $Text = preg_replace("/\[toc([^\]]+?)\]/ism", '<ul id="' . $toc_id . '" class="toc" $1></ul><script>$("#' . $toc_id . '").toc();</script>', $Text, 1);
+ $text = preg_replace("/\[toc([^\]]+?)\]/ism", '<ul id="' . $toc_id . '" class="toc" $1></ul><script>$("#' . $toc_id . '").toc();</script>', $text, 1);
}
// Check for centered text
- if (strpos($Text,'[/center]') !== false) {
- $Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
+ if (strpos($text,'[/center]') !== false) {
+ $text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $text);
}
// Check for footer
- if (strpos($Text,'[/footer]') !== false) {
- $Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $Text);
+ if (strpos($text,'[/footer]') !== false) {
+ $text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $text);
}
// Check for bdi
- if (strpos($Text,'[/bdi]') !== false) {
- $Text = preg_replace("(\[bdi\](.*?)\[\/bdi\])ism", "<bdi>$1</bdi>", $Text);
+ if (strpos($text,'[/bdi]') !== false) {
+ $text = preg_replace("(\[bdi\](.*?)\[\/bdi\])ism", "<bdi>$1</bdi>", $text);
}
// Check for list text
- $Text = preg_replace("/<br \/>\[\*\]/ism",'[*]',$Text);
+ $text = str_replace(["\r\n[*]", "\r[*]", "\n[*]"], "[*]", $text);
+ $text = str_replace("[*]", "<li>", $text);
- $Text = str_replace("[*]", "<li>", $Text);
// handle nested lists
$endlessloop = 0;
- while ((((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false)) ||
- ((strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false)) ||
- ((strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false)) ||
- ((strpos($Text, "[/dl]") !== false) && (strpos($Text, "[dl") !== false)) ||
- ((strpos($Text, "[/li]") !== false) && (strpos($Text, "[li]") !== false))) && (++$endlessloop < 20)) {
- $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet">$1</ul>', $Text);
- $Text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>', $Text);
- $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ul class="listlowerroman" style="list-style-type: lower-roman;">$2</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul>', $Text);
- $Text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul>', $Text);
- $Text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet">$1</ul>', $Text);
- $Text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ul class="listdecimal" style="list-style-type: decimal;">$1</ul>', $Text);
- $Text = preg_replace("/\[\/li\]<br \/>\[li\]/ism",'[/li][li]',$Text);
- $Text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $Text);
+ while ((((strpos($text, "[/list]") !== false) && (strpos($text, "[list") !== false)) ||
+ ((strpos($text, "[/ol]") !== false) && (strpos($text, "[ol]") !== false)) ||
+ ((strpos($text, "[/ul]") !== false) && (strpos($text, "[ul]") !== false)) ||
+ ((strpos($text, "[/dl]") !== false) && (strpos($text, "[dl") !== false)) ||
+ ((strpos($text, "[/li]") !== false) && (strpos($text, "[li]") !== false))) && (++$endlessloop < 20)) {
+
+ $text = str_replace(["[/list]\r", "[/list]\n"], '[/list]', $text);
+
+ $text = preg_replace_callback("/\[list\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet">$1</ul>', $text);
+
+ $text = preg_replace_callback("/\[list=\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list=\](.*?)\[\/list\]/ism", '<ul class="listnone" style="list-style-type: none;">$1</ul>', $text);
+
+ $text = preg_replace_callback("/\[list=1\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ol class="listdecimal" style="list-style-type: decimal;">$1</ol>', $text);
+
+ $text = preg_replace_callback("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list=((?-i)i)\](.*?)\[\/list\]/ism",'<ol class="listlowerroman" style="list-style-type: lower-roman;">$2</ol>', $text);
+
+ $text = preg_replace_callback("/\[list=((?-i)I)\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '<ol class="listupperroman" style="list-style-type: upper-roman;">$2</ol>', $text);
+
+ $text = preg_replace_callback("/\[list=((?-i)a)\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '<ol class="listloweralpha" style="list-style-type: lower-alpha;">$2</ol>', $text);
+
+ $text = preg_replace_callback("/\[list=((?-i)A)\](.*?)\[\/list\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '<ol class="listupperalpha" style="list-style-type: upper-alpha;">$2</ol>', $text);
+
+ $text = preg_replace_callback("/\[ol\](.*?)\[\/ol\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '<ol class="listdecimal" style="list-style-type: decimal;">$1</ol>', $text);
+
+ $text = preg_replace_callback("/\[ul\](.*?)\[\/ul\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '<ul class="listbullet">$1</ul>', $text);
+
+ $text = preg_replace("/\[\/li\]<br \/>\[li\]/ism",'[/li][li]', $text);
+ $text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $text);
// [dl] tags have an optional [dl terms="bi"] form where bold/italic/underline/mono/large
// etc. style may be specified for the "terms" in the definition list. The quotation marks
// are also optional. The regex looks intimidating, but breaks down as:
// "[dl" <optional-whitespace> <optional-termStyles> "]" <matchGroup2> "[/dl]"
// where optional-termStyles are: "terms=" <optional-quote> <matchGroup1> <optional-quote>
- $Text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:&quot;|")?([a-zA-Z]+)(?:&quot;|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $Text);
+ $text = preg_replace_callback('/\[dl[[:space:]]*(?:terms=(?:&quot;|")?([a-zA-Z]+)(?:&quot;|")?)?\](.*?)\[\/dl\]/ism', 'bb_definitionList', $text);
}
- if (strpos($Text,'[checklist]') !== false) {
- $Text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $Text);
+ if (strpos($text,'[checklist]') !== false) {
+ $text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism",'bb_fix_lf', $text);
+ $text = preg_replace_callback("/\[checklist\](.*?)\[\/checklist\]/ism", 'bb_checklist', $text);
}
- if (strpos($Text,'[th]') !== false) {
- $Text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>', $Text);
+ if (strpos($text,'[th]') !== false) {
+ $text = preg_replace("/\[th\](.*?)\[\/th\]/sm", '<th>$1</th>', $text);
}
- if (strpos($Text,'[td]') !== false) {
- $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>', $Text);
+
+ if (strpos($text,'[td]') !== false) {
+ $text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>', $text);
}
- if (strpos($Text,'[tr]') !== false) {
- $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>', $Text);
+
+ if (strpos($text,'[tr]') !== false) {
+ $text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>', $text);
}
- if (strpos($Text,'[/table]') !== false) {
- $Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>', $Text);
- $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table class="table table-responsive table-bordered" >$1</table>', $Text);
- $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table class="table table-responsive" >$1</table>', $Text);
+
+ if (strpos($text,'[/table]') !== false) {
+ $text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fix_lf',$text);
+ $text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>', $text);
+ $text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table class="table table-responsive table-bordered" >$1</table>', $text);
+ $text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table class="table table-responsive" >$1</table>', $text);
}
- $Text = str_replace('</tr><br /><tr>', "</tr>\n<tr>", $Text);
- $Text = str_replace('[hr]', '<hr />', $Text);
+
+ $text = str_replace('[hr]', '<hr />', $text);
// This is actually executed in prepare_body()
- $Text = str_replace('[nosmile]', '', $Text);
+ $text = str_replace('[nosmile]', '', $text);
// Check for font change text
- if (strpos($Text,'[/font]') !== false) {
- $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $Text);
+ if (strpos($text,'[/font]') !== false) {
+ $text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $text);
}
// Check for [spoiler] text
$endlessloop = 0;
- while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text);
+ while ((strpos($text, "[/spoiler]")!== false) and (strpos($text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $text);
}
// Check for [spoiler=Author] text
$endlessloop = 0;
- while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text);
+ while ((strpos($text, "[/spoiler]")!== false) and (strpos($text, "[spoiler=") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $text);
}
// Check for [open] text
$endlessloop = 0;
- while ((strpos($Text, "[/open]")!== false) and (strpos($Text, "[open]") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $Text);
+ while ((strpos($text, "[/open]")!== false) and (strpos($text, "[open]") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $text);
}
// Check for [open=Title] text
$endlessloop = 0;
- while ((strpos($Text, "[/open]")!== false) and (strpos($Text, "[open=") !== false) and (++$endlessloop < 20)) {
- $Text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $Text);
+ while ((strpos($text, "[/open]")!== false) and (strpos($text, "[open=") !== false) and (++$endlessloop < 20)) {
+ $text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $text);
}
@@ -1528,8 +1614,8 @@ function bbcode($Text, $options = []) {
// Check for [quote] text
// handle nested quotes
$endlessloop = 0;
- while ((strpos($Text, "[/quote]") !== false) and (strpos($Text, "[quote]") !== false) and (++$endlessloop < 20))
- $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $Text);
+ while ((strpos($text, "[/quote]") !== false) and (strpos($text, "[quote]") !== false) and (++$endlessloop < 20))
+ $text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism", "$QuoteLayout", $text);
// Check for [quote=Author] text
@@ -1537,119 +1623,120 @@ function bbcode($Text, $options = []) {
// handle nested quotes
$endlessloop = 0;
- while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20))
- $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
+ while ((strpos($text, "[/quote]")!== false) and (strpos($text, "[quote=") !== false) and (++$endlessloop < 20))
+ $text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
"<span class=".'"bb-quote"'.">" . $t_wrote . "</span><blockquote>$2</blockquote>",
- $Text);
+ $text);
// Images
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace_callback('/\[\$b64img(.*?)\[\/(img)\]/ism','\red_unescape_codeblock',$Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace_callback('/\[\$b64img(.*?)\[\/(img)\]/ism','\red_unescape_codeblock',$text);
}
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace_callback('/\[\$b64zmg(.*?)\[\/(zmg)\]/ism','\red_unescape_codeblock',$Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace_callback('/\[\$b64zmg(.*?)\[\/(zmg)\]/ism','\red_unescape_codeblock',$text);
}
// [img]pathtoimage[/img]
- if (strpos($Text,'[/img]') !== false) {
+ if (strpos($text,'[/img]') !== false) {
- $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $Text);
+ $text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $text);
}
// [img=pathtoimage]image description[/img]
- if (strpos($Text,'[/img]') !== false) {
- $Text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $Text);
+ if (strpos($text,'[/img]') !== false) {
+ $text = preg_replace("/\[img=http(.*?)\](.*?)\[\/img\]/ism", '<img style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $text);
}
// [zmg]pathtoimage[/zmg]
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="$1" alt="' . t('Image/photo') . '" loading="eager" />', $text);
}
// [zmg=pathtoimage]image description[/zmg]
- if (strpos($Text,'[/zmg]') !== false) {
- $Text = preg_replace("/\[zmg=http(.*?)\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $Text);
+ if (strpos($text,'[/zmg]') !== false) {
+ $text = preg_replace("/\[zmg=http(.*?)\](.*?)\[\/zmg\]/ism", '<img class="zrl" style="max-width: 100%;" src="http$1" alt="$2" title="$2" loading="eager" />', $text);
}
- $Text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$Text);
+ $text = preg_replace_callback("/\[([zi])mg([ \=])(.*?)\](.*?)\[\/[zi]mg\]/ism",'bb_imgoptions',$text);
// style (sanitized)
- if (strpos($Text,'[/style]') !== false) {
- $Text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $Text);
+ if (strpos($text,'[/style]') !== false) {
+ $text = preg_replace_callback("(\[style=(.*?)\](.*?)\[\/style\])ism", "bb_sanitize_style", $text);
}
// crypt
- if (strpos($Text,'[/crypt]') !== false) {
- $x = random_string();
- $Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img class="cursor-pointer" src="' .z_root() . '/images/lock_icon.svg" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text);
- $Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text);
+ if (strpos($text,'[/crypt]') !== false) {
+ $text = preg_replace_callback("/\[crypt\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $text);
+ $text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $text);
}
- if(strpos($Text,'[/app]') !== false) {
- $Text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app', $Text);
+ if(strpos($text,'[/app]') !== false) {
+ $text = preg_replace_callback("/\[app\](.*?)\[\/app\]/ism",'bb_parse_app', $text);
}
- if(strpos($Text,'[/element]') !== false) {
- $Text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism",'bb_parse_element', $Text);
+ if(strpos($text,'[/element]') !== false) {
+ $text = preg_replace_callback("/\[element\](.*?)\[\/element\]/ism",'bb_parse_element', $text);
}
// html5 video and audio
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $Text);
- $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace_callback("/\[video (.*?)\](.*?)\[\/video\]/ism", 'videowithopts', $text);
+ $text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryzrlvideo', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryzrlaudio', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $Text);
- $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace_callback("/\[zvideo (.*?)\](.*?)\[\/zvideo\]/ism", 'videowithopts', $text);
+ $text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryzrlvideo', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryzrlaudio', $text);
}
// SVG stuff
- $Text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $Text);
+ $text = preg_replace_callback("/\[svg(.*?)\](.*?)\[\/svg\]/ism", 'bb_svg', $text);
// Try to Oembed
if ($tryoembed) {
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace_callback("/\[zvideo\](.*?)\[\/zvideo\]/ism", 'tryoembed', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryoembed', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace_callback("/\[zaudio\](.*?)\[\/zaudio\]/ism", 'tryoembed', $text);
}
}
// if video couldn't be embedded, link to it instead.
- if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/video]') !== false) {
+ $text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
- if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/audio]') !== false) {
+ $text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
- if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/zvideo]') !== false) {
+ $text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
- if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
+ if (strpos($text,'[/zaudio]') !== false) {
+ $text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $text);
}
// oembed tag
- $Text = oembed_bbcode2html($Text);
+ if (strpos($text,'[/embed]') !== false) {
+ $text = oembed_bbcode2html($text);
- // Avoid triple linefeeds through oembed
- $Text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $Text);
+ // Avoid triple linefeeds through oembed
+ $text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span>", $text);
+ }
// If we found an event earlier, strip out all the event code and replace with a reformatted version.
// Replace the event-start section with the entire formatted event. The other bbcode is stripped.
@@ -1662,72 +1749,73 @@ function bbcode($Text, $options = []) {
$sub = str_replace('$',"\0",$sub);
- $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text);
+ $text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$text);
- $Text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-timezone\](.*?)\[\/event\-timezone\]/ism",'',$Text);
- $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
+ $text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$text);
+ $text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$text);
+ $text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$text);
+ $text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$text);
+ $text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism",'',$text);
+ $text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$text);
+ $text = preg_replace("/\[event\-timezone\](.*?)\[\/event\-timezone\]/ism",'',$text);
+ $text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$text);
- $Text = str_replace("\0",'$',$Text);
+ $text = str_replace("\0",'$',$text);
}
- if (strpos($Text,'[summary]') !== false) {
- $Text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_unspacefy',$Text);
+ if (strpos($text,'[summary]') !== false) {
+ $text = preg_replace_callback("/\[summary\](.*?)\[\/summary\]/ism", 'bb_unspacefy',$text);
}
- if(strpos($Text,'[/summary]') !== false) {
- $Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/is", 'bb_summary', $Text);
+ if(strpos($text,'[/summary]') !== false) {
+ $text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/is", 'bb_summary', $text);
}
// Unhide all [noparse] contained bbtags unspacefying them
// and triming the [noparse] tag.
- if (strpos($Text,'[noparse]') !== false) {
- $Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text);
+ if (strpos($text,'[noparse]') !== false) {
+ $text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $text);
}
- if (strpos($Text,'[nobb]') !== false) {
- $Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text);
+ if (strpos($text,'[nobb]') !== false) {
+ $text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $text);
}
- if (strpos($Text,'[pre]') !== false) {
- $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text);
+ if (strpos($text,'[pre]') !== false) {
+ $text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $text);
}
// replace escaped links in code= blocks
- $Text = str_replace('%eY9-!','http', $Text);
- $Text = bb_code_unprotect($Text);
+ $text = str_replace('%eY9-!','http', $text);
+ $text = bb_code_unprotect($text);
- $Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $Text);
+ $text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $text);
// fix any escaped ampersands that may have been converted into links
- if(strpos($Text,'&amp;') !== false)
- $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text);
+ if(strpos($text,'&amp;') !== false)
+ $text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $text);
// This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where
// the scheme begins with z (zhttp), h (http(s)), f (ftp(s)), m (mailto), t (tel) and named anchors.
- $Text = preg_replace("/\<(.*?)(src|href)=\"[^zhfmt#](.*?)\>/ism", '<$1$2="">', $Text);
+ $text = preg_replace("/\<(.*?)(src|href)=\"[^zhfmt#](.*?)\>/ism", '<$1$2="">', $text);
- $Text = bb_replace_images($Text, $saved_images);
+ $text = bb_replace_images($text, $saved_images);
// Convert new line chars to html <br /> tags
// nlbr seems to be hopelessly messed up
- // $Text = nl2br($Text);
+ // $text = nl2br($text);
// We'll emulate it.
- $Text = str_replace("\r\n", "\n", $Text);
- $Text = str_replace(array("\r", "\n"), array('<br />', '<br />'), $Text);
-
- if ($preserve_nl)
- $Text = str_replace(array("\n", "\r"), array('', ''), $Text);
+ $text = str_replace("\r\n", "\n", $text);
+ $text = str_replace(["\r", "\n"], '<br />', $text);
- call_hooks('bbcode', $Text);
+ /**
+ * @hooks bbcode
+ * * _string_ **html** - The resulting HTML after converting from bbcode.
+ */
+ call_hooks('bbcode', $text);
- return $Text;
+ return $text;
}
diff --git a/include/channel.php b/include/channel.php
index 640274348..a82794bfd 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -16,6 +16,7 @@ use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Connect;
use Zotlabs\Lib\Libsync;
use Zotlabs\Lib\AccessList;
+use Zotlabs\Lib\Multibase;
require_once('include/crypto.php');
require_once('include/menu.php');
@@ -236,6 +237,10 @@ function create_identity($arr) {
$guid = Libzot::new_uid($nick);
$key = Crypto::new_keypair(4096);
+ $eckey = sodium_crypto_sign_keypair();
+ $ekey['pubkey'] = sodium_bin2base64(sodium_crypto_sign_publickey($eckey), SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
+ $ekey['prvkey'] = sodium_bin2base64(sodium_crypto_sign_secretkey($eckey), SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
+
// zot6
$sig = Libzot::sign($guid,$key['prvkey']);
$hash = Libzot::make_xchan_hash($guid,$key['pubkey']);
@@ -275,6 +280,8 @@ function create_identity($arr) {
'channel_portable_id' => '',
'channel_prvkey' => $key['prvkey'],
'channel_pubkey' => $key['pubkey'],
+ 'channel_eprvkey' => $ekey['prvkey'],
+ 'channel_epubkey' => $ekey['pubkey'],
'channel_pageflags' => intval($pageflags),
'channel_system' => intval($system),
'channel_expire_days' => intval($expire),
@@ -370,6 +377,7 @@ function create_identity($arr) {
'xchan_guid' => $guid,
'xchan_guid_sig' => $sig,
'xchan_pubkey' => $key['pubkey'],
+ 'xchan_epubkey' => (new Multibase())->publicKey($ekey['pubkey']),
'xchan_photo_mimetype' => (($photo_type) ? $photo_type : 'image/png'),
'xchan_photo_l' => z_root() . "/photo/profile/l/{$newuid}",
'xchan_photo_m' => z_root() . "/photo/profile/m/{$newuid}",
@@ -1763,17 +1771,19 @@ function advanced_profile() {
if(App::$profile['gender']) $profile['gender'] = array( t('Gender:'), App::$profile['gender'] );
$ob_hash = get_observer_hash();
+/* TODO: AS2 compatibility
if($ob_hash && perm_is_allowed(App::$profile['profile_uid'],$ob_hash,'post_like')) {
$profile['canlike'] = true;
$profile['likethis'] = t('Like this channel');
$profile['profile_guid'] = App::$profile['profile_guid'];
}
- $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and target_type = '%s' and verb = '%s'",
+ $likers = q("select liker, xchan.* from likes left join xchan on liker = xchan_hash where channel_id = %d and (target_type = 'Profile' OR target_type = '%s') and (verb = 'Like' OR verb = '%s')",
intval(App::$profile['profile_uid']),
dbesc(ACTIVITY_OBJ_PROFILE),
dbesc(ACTIVITY_LIKE)
);
+
$profile['likers'] = array();
$profile['like_count'] = count($likers);
$profile['like_button_label'] = tt('Like','Likes',$profile['like_count'],'noun');
@@ -1781,7 +1791,7 @@ function advanced_profile() {
foreach($likers as $l)
$profile['likers'][] = array('name' => $l['xchan_name'],'photo' => zid($l['xchan_photo_s']), 'url' => zid($l['xchan_url']));
}
-
+*/
if((App::$profile['dob']) && (App::$profile['dob'] != '0000-00-00')) {
$val = '';
@@ -2642,6 +2652,8 @@ function channel_store_lowlevel($arr) {
'channel_startpage' => ((array_key_exists('channel_startpage',$arr)) ? $arr['channel_startpage'] : ''),
'channel_pubkey' => ((array_key_exists('channel_pubkey',$arr)) ? $arr['channel_pubkey'] : ''),
'channel_prvkey' => ((array_key_exists('channel_prvkey',$arr)) ? $arr['channel_prvkey'] : ''),
+ 'channel_epubkey' => ((array_key_exists('channel_epubkey',$arr)) ? $arr['channel_epubkey'] : ''),
+ 'channel_eprvkey' => ((array_key_exists('channel_eprvkey',$arr)) ? $arr['channel_eprvkey'] : ''),
'channel_notifyflags' => ((array_key_exists('channel_notifyflags',$arr)) ? $arr['channel_notifyflags'] : '65535'),
'channel_pageflags' => ((array_key_exists('channel_pageflags',$arr)) ? $arr['channel_pageflags'] : '0'),
'channel_dirdate' => ((array_key_exists('channel_dirdate',$arr)) ? $arr['channel_dirdate'] : NULL_DATE),
diff --git a/include/contact_widgets.php b/include/contact_widgets.php
index 182f674ca..c05ecaf7c 100644
--- a/include/contact_widgets.php
+++ b/include/contact_widgets.php
@@ -85,7 +85,7 @@ function categories_widget($baseurl,$selected = '') {
AND term.otype = %d
AND item.owner_xchan = '%s'
AND item.item_wall = 1
- AND item.verb != '%s'
+ AND item.verb NOT IN ('Update', '%s')
$item_normal
$sql_extra
ORDER BY term.term ASC",
diff --git a/include/conversation.php b/include/conversation.php
index faa53c639..79fe12d54 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -90,7 +90,7 @@ function item_redir_and_replace_images($body, $images, $cid) {
function localize_item(&$item){
- if (activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)){
+ if (activity_match($item['verb'], ['Like', 'Dislike', ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_SHARE])){
if(! $item['obj'])
return;
@@ -143,7 +143,7 @@ function localize_item(&$item){
switch($obj['type']) {
case ACTIVITY_OBJ_PHOTO:
- case 'Photo':
+ case 'Image':
$post_type = t('photo');
break;
case ACTIVITY_OBJ_EVENT:
@@ -151,6 +151,7 @@ function localize_item(&$item){
$post_type = t('event');
break;
case ACTIVITY_OBJ_PERSON:
+ case 'Person':
$post_type = t('channel');
$author_name = $obj['title'];
if($obj['link']) {
@@ -189,21 +190,19 @@ function localize_item(&$item){
$plink = '[zrl=' . zid($item_url) . ']' . $post_type . '[/zrl]';
- if(activity_match($item['verb'],ACTIVITY_LIKE)) {
+ if(activity_match($item['verb'], ['Like', ACTIVITY_LIKE])) {
$bodyverb = t('%1$s likes %2$s\'s %3$s');
- }
- elseif(activity_match($item['verb'],ACTIVITY_DISLIKE)) {
- $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
- }
-
- // short version, in notification strings the author will be displayed separately
-
- if(activity_match($item['verb'],ACTIVITY_LIKE)) {
+ // short version, in notification strings the author will be displayed separately
$shortbodyverb = t('likes %1$s\'s %2$s');
}
- elseif(activity_match($item['verb'],ACTIVITY_DISLIKE)) {
+ elseif(activity_match($item['verb'], ['Dislike', ACTIVITY_DISLIKE])) {
+ $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
$shortbodyverb = t('doesn\'t like %1$s\'s %2$s');
}
+ elseif(activity_match($item['verb'], ACTIVITY_SHARE)) {
+ $bodyverb = t('%1$s repeated %2$s\'s %3$s');
+ $shortbodyverb = t('repeated %1$s\'s %2$s');
+ }
$item['shortlocalize'] = sprintf($shortbodyverb, '[bdi]' . $author_name . '[/bdi]', $post_type);
@@ -218,191 +217,6 @@ function localize_item(&$item){
}
- if (activity_match($item['verb'],ACTIVITY_FRIEND)) {
-
- if ($item['obj_type'] == "" || $item['obj_type'] !== ACTIVITY_OBJ_PERSON)
- return;
-
- $Aname = $item['author']['xchan_name'];
- $Alink = $item['author']['xchan_url'];
-
-
- $obj= json_decode($item['obj'],true);
-
- $Blink = $Bphoto = '';
-
- if($obj['link']) {
- $Blink = get_rel_link($obj['link'],'alternate');
- $Bphoto = get_rel_link($obj['link'],'photo');
- }
- $Bname = $obj['title'];
-
-
- $A = '[zrl=' . chanlink_url($Alink) . '][bdi]' . $Aname . '[/bdi][/zrl]';
- $B = '[zrl=' . chanlink_url($Blink) . '][bdi]' . $Bname . '[/bdi][/zrl]';
- if ($Bphoto!="") $Bphoto = '[zrl=' . chanlink_url($Blink) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]';
-
- $item['shortlocalize'] = sprintf( t('%1$s is now connected with %2$s'), '[bdi]' . $Aname . '[/bdi]', '[bdi]' . $Bname . '[/bdi]');
-
- $item['body'] = $item['localize'] = sprintf( t('%1$s is now connected with %2$s'), $A, $B);
- $item['body'] .= "\n\n\n" . $Bphoto;
- }
-
- if (stristr($item['verb'], ACTIVITY_POKE)) {
-
- /** @FIXME for obscured private posts, until then leave untranslated */
- return;
-
- $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
- if(! $verb)
- return;
-
- if ($item['obj_type']=="" || $item['obj_type']!== ACTIVITY_OBJ_PERSON) return;
-
- $Aname = $item['author']['xchan_name'];
- $Alink = $item['author']['xchan_url'];
-
- $obj= json_decode($item['obj'],true);
-
- $Blink = $Bphoto = '';
-
- if($obj['link']) {
- $Blink = get_rel_link($obj['link'],'alternate');
- $Bphoto = get_rel_link($obj['link'],'photo');
- }
- $Bname = $obj['title'];
-
- $A = '[zrl=' . chanlink_url($Alink) . '][bdi]' . $Aname . '[/bdi][/zrl]';
- $B = '[zrl=' . chanlink_url($Blink) . '][bdi]' . $Bname . '[/bdi][/zrl]';
- if ($Bphoto!="") $Bphoto = '[zrl=' . chanlink_url($Blink) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]';
-
- // we can't have a translation string with three positions but no distinguishable text
- // So here is the translate string.
-
- $txt = t('%1$s poked %2$s');
-
- // now translate the verb
-
- $txt = str_replace( t('poked'), t($verb), $txt);
-
- // then do the sprintf on the translation string
-
- $item['shortlocalize'] = sprintf($txt, '[bdi]' . $Aname . '[/bdi]', '[bdi]' . $Bname . '[/bdi]');
-
- $item['body'] = $item['localize'] = sprintf($txt, $A, $B);
- $item['body'] .= "\n\n\n" . $Bphoto;
- }
- if (stristr($item['verb'],ACTIVITY_MOOD)) {
- $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
- if(! $verb)
- return;
-
- $Aname = $item['author']['xchan_name'];
- $Alink = $item['author']['xchan_url'];
-
- $A = '[zrl=' . chanlink_url($Alink) . '][bdi]' . $Aname . '[/bdi][/zrl]';
-
- $txt = t('%1$s is %2$s','mood');
-
- $item['body'] = sprintf($txt, $A, t($verb));
- }
-
-
-
-/*
-// FIXME store parent item as object or target
-// (and update to json storage)
-
- if (activity_match($item['verb'],ACTIVITY_TAG)) {
- $r = q("SELECT * from item,contact WHERE
- item.contact-id=contact.id AND item.mid='%s';",
- dbesc($item['parent_mid']));
- if(count($r)==0) return;
- $obj=$r[0];
-
- $author = '[zrl=' . zid($item['author-link']) . ']' . $item['author-name'] . '[/zrl]';
- $objauthor = '[zrl=' . zid($obj['author-link']) . ']' . $obj['author-name'] . '[/zrl]';
-
- switch($obj['verb']){
- case ACTIVITY_POST:
- switch ($obj['obj_type']){
- case ACTIVITY_OBJ_EVENT:
- $post_type = t('event');
- break;
- default:
- $post_type = t('status');
- }
- break;
- default:
- if($obj['resource_id']){
- $post_type = t('photo');
- $m=array(); preg_match("/\[[zu]rl=([^]]*)\]/", $obj['body'], $m);
- $rr['plink'] = $m[1];
- } else {
- $post_type = t('status');
- }
- }
- $plink = '[zrl=' . $obj['plink'] . ']' . $post_type . '[/zrl]';
-
-// $parsedobj = parse_xml_string($xmlhead.$item['obj']);
-
- $tag = sprintf('#[zrl=%s]%s[/zrl]', $parsedobj->id, $parsedobj->content);
- $item['body'] = sprintf( t('%1$s tagged %2$s\'s %3$s with %4$s'), $author, $objauthor, $plink, $tag );
-
- }
-
- if (activity_match($item['verb'],ACTIVITY_FAVORITE)){
-
- if ($item['obj_type']== "")
- return;
-
- $Aname = $item['author']['xchan_name'];
- $Alink = $item['author']['xchan_url'];
-
- $xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
-
-// $obj = parse_xml_string($xmlhead.$item['obj']);
- if(strlen($obj->id)) {
- $r = q("select * from item where mid = '%s' and uid = %d limit 1",
- dbesc($obj->id),
- intval($item['uid'])
- );
- if(count($r) && $r[0]['plink']) {
- $target = $r[0];
- $Bname = $target['author-name'];
- $Blink = $target['author-link'];
- $A = '[zrl=' . zid($Alink) . ']' . $Aname . '[/zrl]';
- $B = '[zrl=' . zid($Blink) . ']' . $Bname . '[/zrl]';
- $P = '[zrl=' . $target['plink'] . ']' . t('post/item') . '[/zrl]';
- $item['body'] = sprintf( t('%1$s marked %2$s\'s %3$s as favorite'), $A, $B, $P)."\n";
-
- }
- }
- }
-*/
-
-/*
- $matches = null;
- if(strpos($item['body'],'[zrl') !== false) {
- if(preg_match_all('/@\[zrl=(.*?)\]/is',$item['body'],$matches,PREG_SET_ORDER)) {
- foreach($matches as $mtch) {
- if(! strpos($mtch[1],'zid='))
- $item['body'] = str_replace($mtch[0],'@[zrl=' . zid($mtch[1]). ']',$item['body']);
- }
- }
- }
-
- if(strpos($item['body'],'[zmg') !== false) {
- // add zid's to public images
- if(preg_match_all('/\[zrl=(.*?)\/photos\/(.*?)\/image\/(.*?)\]\[zmg(.*?)\]h(.*?)\[\/zmg\]\[\/zrl\]/is',$item['body'],$matches,PREG_SET_ORDER)) {
- foreach($matches as $mtch) {
- $item['body'] = str_replace($mtch[0],'[zrl=' . zid( $mtch[1] . '/photos/' . $mtch[2] . '/image/' . $mtch[3]) . '][zmg' . $mtch[4] . ']h' . $mtch[5] . '[/zmg][/zrl]',$item['body']);
- }
- }
- }
-*/
-
-
}
/**
@@ -441,7 +255,7 @@ function count_descendants($item) {
* @return boolean
*/
function visible_activity($item) {
- $hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_POLLRESPONSE ];
+ $hidden_activities = ['Like', 'Dislike', 'Accept', 'Reject', 'TentativeAccept', ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_SHARE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE];
if(intval($item['item_notshown']))
return false;
@@ -450,7 +264,7 @@ function visible_activity($item) {
return false;
}
- if (in_array($item['verb'], ['Add', 'Remove', ACTIVITY_TAG])) {
+ if (in_array($item['verb'], ['Add', 'Remove'])) {
return false;
}
@@ -476,27 +290,6 @@ function visible_activity($item) {
return true;
}
-/**
- * @brief Check if a given activity is an edit activity
- *
- *
- * @param array $item
- * @return boolean
- */
-
-function is_edit_activity($item) {
-
- $post_types = [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, basename(ACTIVITY_OBJ_NOTE), basename(ACTIVITY_OBJ_COMMENT)];
-
- // In order to share edits with networks which have no concept of editing, we'll create
- // separate activities to indicate the edit. Our network will not require them, since our
- // edits are automatically applied and the activity indicated.
-
- if(($item['verb'] === ACTIVITY_UPDATE) && (in_array($item['obj_type'],$post_types)))
- return true;
-
- return false;
-}
/**
* @brief "Render" a conversation or list of items for HTML display.
@@ -670,13 +463,11 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
$conv_responses = [
'like' => ['title' => t('Likes','title')],
'dislike' => ['title' => t('Dislikes','title')],
- 'agree' => ['title' => t('Agree','title')],
- 'disagree' => ['title' => t('Disagree','title')],
- 'abstain' => ['title' => t('Abstain','title')],
'attendyes' => ['title' => t('Attending','title')],
'attendno' => ['title' => t('Not attending','title')],
'attendmaybe' => ['title' => t('Might attend','title')],
- 'answer' => []
+ 'answer' => [],
+ 'announce' => ['title' => t('Repeats','title')],
];
@@ -718,9 +509,9 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
$is_new = false;
if($mode === 'search' || $mode === 'community') {
- if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE)))
- && ($item['id'] != $item['parent']))
+ if(activity_match($item['verb'], ['Like', 'Dislike', ACTIVITY_LIKE, ACTIVITY_DISLIKE]) && $item['id'] != $item['parent']) {
continue;
+ }
}
$sp = false;
@@ -785,16 +576,14 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
$is_new = true;
- $conv_link_mid = (($mode == 'moderate') ? gen_link_id($item['parent_mid']) : gen_link_id($item['mid']));
-
- $conv_link = z_root() . '/display/' . $conv_link_mid;
+ $conv_link = z_root() . '/display/' . $item['uuid'];
if(local_channel()) {
- $conv_link = z_root() . '/hq/' . $conv_link_mid;
+ $conv_link = z_root() . '/hq/' . $item['uuid'];
}
if ($mode === 'pubstream-new') {
- $conv_link = z_root() . '/pubstream?mid=' . $conv_link_mid;
+ $conv_link = z_root() . '/pubstream?mid=' . $item['uuid'];
}
$contact = [];
@@ -812,8 +601,8 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
'delete' => t('Delete'),
'preview_lbl' => $preview_lbl,
'id' => (($preview) ? 'P0' : $item['item_id']),
- 'mid' => gen_link_id($item['mid']),
- 'mids' => json_encode([gen_link_id($item['mid'])]),
+ 'mid' => $item['uuid'],
+ 'mids' => json_encode([$item['uuid']]),
'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, $profile_link),
'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
'profile_url' => $profile_link,
@@ -914,7 +703,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
continue;
}
-
+ $mid_uuid_map[$item['mid']] = $item['uuid'];
$item['pagedrop'] = $page_dropping;
@@ -934,7 +723,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
}
}
- $threads = $conv->get_template_data($conv_responses);
+ $threads = $conv->get_template_data($conv_responses, $mid_uuid_map);
if(!$threads) {
logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG);
$threads = array();
@@ -1091,13 +880,10 @@ function thread_author_menu($item, $mode = '') {
}
}
-
$contact_url = '';
$posts_link = '';
- $poke_link = '';
if($contact) {
- $poke_link = ((Apps::system_app_installed($local_channel, 'Poke')) ? z_root() . '/poke/?f=&c=' . $contact['abook_id'] : '');
if (isset($contact['abook_self']) && !intval($contact['abook_self']))
$contact_url = z_root() . '/connections#' . $contact['abook_id'];
$posts_link = z_root() . '/network/?cid=' . $contact['abook_id'];
@@ -1151,18 +937,6 @@ function thread_author_menu($item, $mode = '') {
];
}
- if($poke_link) {
- $menu[] = [
- 'menu' => 'poke',
- 'title' => t('Poke'),
- 'icon' => 'fw',
- 'action' => '',
- 'href' => $poke_link,
- 'data' => '',
- 'class' => ''
- ];
- }
-
$args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ];
call_hooks('thread_author_menu', $args);
@@ -1186,7 +960,7 @@ function builtin_activity_puller($item, &$conv_responses) {
// if this item is a post or comment there's nothing for us to do here, just return.
- if(activity_match($item['verb'],ACTIVITY_POST) && $item['obj_type'] !== 'Answer')
+ if(activity_match($item['verb'], ['Create', ACTIVITY_POST]) && $item['obj_type'] !== 'Answer')
return;
foreach($conv_responses as $mode => $v) {
@@ -1195,31 +969,25 @@ function builtin_activity_puller($item, &$conv_responses) {
switch($mode) {
case 'like':
- $verb = ACTIVITY_LIKE;
+ $verb = ['Like', ACTIVITY_LIKE];
break;
case 'dislike':
- $verb = ACTIVITY_DISLIKE;
- break;
- case 'agree':
- $verb = ACTIVITY_AGREE;
- break;
- case 'disagree':
- $verb = ACTIVITY_DISAGREE;
- break;
- case 'abstain':
- $verb = ACTIVITY_ABSTAIN;
+ $verb = ['Dislike', ACTIVITY_DISLIKE];
break;
case 'attendyes':
- $verb = ACTIVITY_ATTEND;
+ $verb = ['Accept', ACTIVITY_ATTEND];
break;
case 'attendno':
- $verb = ACTIVITY_ATTENDNO;
+ $verb = ['Reject', ACTIVITY_ATTENDNO];
break;
case 'attendmaybe':
- $verb = ACTIVITY_ATTENDMAYBE;
+ $verb = ['TentativeAccept', ACTIVITY_ATTENDMAYBE];
break;
case 'answer':
- $verb = ACTIVITY_POST;
+ $verb = ['Create', ACTIVITY_POST];
+ break;
+ case 'announce':
+ $verb = 'Announce';
break;
default:
return;
@@ -1227,6 +995,7 @@ function builtin_activity_puller($item, &$conv_responses) {
}
if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) {
+
$name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown'));
$moderate = ((intval($item['item_blocked']) === ITEM_MODERATED) ? '<a href="moderate/' . $item['id'] . '/approve" onclick="moderate_approve(' . $item['id'] . '); return false;" class="text-success pe-2" title="' . t('Approve this item') . '"><i class="fa fa-check" ></i></a><a href="moderate/' . $item['id'] . '/drop" onclick="moderate_drop(' . $item['id'] . '); return false;" class="text-danger pe-2" title="' . t('Delete this item') . '"><i class="fa fa-trash-o" ></i></a>' : '');
@@ -1241,7 +1010,7 @@ function builtin_activity_puller($item, &$conv_responses) {
if(! $item['thr_parent'])
$item['thr_parent'] = $item['parent_mid'];
- $conv_responses[$mode]['mids'][$item['thr_parent']][] = gen_link_id($item['mid']);
+ $conv_responses[$mode]['mids'][$item['thr_parent']][] = $item['uuid'];
if($item['obj_type'] === 'Answer')
continue;
@@ -1778,28 +1547,22 @@ function get_responses($conv_responses,$response_verbs,$ob,$item) {
function get_response_button_text($v,$count) {
switch($v) {
case 'like':
- return tt('Like','Likes',$count,'noun');
+ return ['label' => tt('Like','Likes',$count,'noun'), 'icon' => 'thumbs-o-up', 'class' => 'like'];
+ break;
+ case 'announce':
+ return ['label' => tt('Repeat','Repeats',$count,'noun'), 'icon' => 'retweet', 'class' => 'announce'];
break;
case 'dislike':
- return tt('Dislike','Dislikes',$count,'noun');
+ return ['label' => tt('Dislike','Dislikes',$count,'noun'), 'icon' => 'thumbs-o-down', 'class' => 'dislike'];
break;
case 'attendyes':
- return tt('Attending','Attending',$count,'noun');
+ return ['label' => tt('Attending','Attending',$count,'noun'), 'icon' => 'calendar-check-o', 'class' => 'attendyes'];
break;
case 'attendno':
- return tt('Not Attending','Not Attending',$count,'noun');
+ return ['label' => tt('Not Attending','Not Attending',$count,'noun'), 'icon' => 'calendar-times-o', 'class' => 'attendno'];
break;
case 'attendmaybe':
- return tt('Undecided','Undecided',$count,'noun');
- break;
- case 'agree':
- return tt('Agree','Agrees',$count,'noun');
- break;
- case 'disagree':
- return tt('Disagree','Disagrees',$count,'noun');
- break;
- case 'abstain':
- return tt('Abstain','Abstains',$count,'noun');
+ return ['label' => tt('Undecided','Undecided',$count,'noun'), 'icon' => 'calendar-o', 'class' => 'attendmaybe'];
break;
default:
return '';
diff --git a/include/dba/dba_transaction.php b/include/dba/dba_transaction.php
new file mode 100644
index 000000000..02e9945ca
--- /dev/null
+++ b/include/dba/dba_transaction.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Class to represent a database transaction.
+ *
+ * A database transaction is initiated upon construction of an object of this
+ * class. The transaction will be automatically rolled back upon destruction
+ * unless it has been explicitly committed by calling the `commit` method.
+ *
+ * Wrapping multiple database operation within a transaction ensures that all
+ * (or none) of the operations are successfully completed at the same time.
+ *
+ * If a transaction is already active when constructing an object of this
+ * class, it will _not_ try to initiate a transaction, but constructs an object
+ * that will in practice be a stub. This prevents that "nested" transactions
+ * will cause problems with the existing active transaction.
+ *
+ * It also means that any rollbacks or commits perfomed on the "nested"
+ * transaction will be ignored, and postponed to the outer transaction is
+ * committed or rolled back.
+ *
+ * Also note that any modification to the database schema will implicitly
+ * commit active transactions in most cases, so be careful about relying on
+ * transactions in those cases.
+ *
+ * @Note This class assumes the actual underlying database driver is PDO.
+ */
+class DbaTransaction {
+ private bool $committed = false;
+ private bool $active = false;
+
+ /**
+ * Creates a database transaction object.
+ *
+ * If a transaction is already active for this db connection,
+ * no transaction is initiated, and the constructed object will
+ * not perform any commit or rollback actions.
+ */
+ public function __construct(private dba_driver $dba) {
+ if (! $this->dba->db->inTransaction()) {
+ $this->active = $this->dba->db->beginTransaction();
+ }
+ }
+
+ /**
+ * Roll back the transaction if it is active and not already committed.
+ */
+ public function __destruct() {
+ if ($this->active && ! $this->committed) {
+ $this->dba->db->rollBack();
+ }
+ }
+
+ /**
+ * Commit the transaction if active.
+ *
+ * This will also mark the transaction as committed, preventing it from
+ * being attempted rolled back on destruction.
+ */
+ public function commit(): void {
+ if ($this->active && ! $this->committed) {
+ $this->committed = $this->dba->db->commit();
+ }
+ }
+}
diff --git a/include/event.php b/include/event.php
index 745469064..701f3c330 100644
--- a/include/event.php
+++ b/include/event.php
@@ -58,7 +58,9 @@ function format_event_html($ev) {
$ev['dtend'] , $bd_format )))
. '</span></div>' . "\r\n";
- $o .= '<div class="event-description">' . zidify_links(smilies(bbcode($ev['description']))) . '</div>' . "\r\n";
+ if (!empty($ev['description'])) {
+ $o .= '<div class="event-description">' . zidify_links(smilies(bbcode($ev['description']))) . '</div>' . "\r\n";
+ }
if(isset($ev['location']) && $ev['location'])
$o .= '<div class="event-location"><span class="event-label"> ' . t('Location:') . '</span>&nbsp;<span class="location">'
@@ -117,6 +119,7 @@ function format_event_obj($jobject) {
$dtdiff = $dtstart->diff($dtend_obj);
+ $oneday = false;
if($allday && ($dtdiff->days < 2))
$oneday = true;
@@ -993,7 +996,7 @@ function event_import_ical($ical, $uid) {
$ev['timezone'] = 'UTC';
// Try to get an usable olson format timezone
- if($ev['adjust']) {
+ if($ev['adjust'] && isset($ical->DTSTART['TZID'])) {
//TODO: we should pass the vcalendar to getTimeZone() to be more accurate
// we do not have it here since parse_ical_file() is passing the vevent only.
$timezone_obj = \Sabre\VObject\TimeZoneUtil::getTimeZone($ical->DTSTART['TZID']);
@@ -1308,7 +1311,7 @@ function event_store_item($arr, $event) {
dbesc($sig),
intval($r[0]['item_flags']),
intval($private),
- dbesc(ACTIVITY_OBJ_EVENT),
+ dbesc('Event'),
intval($r[0]['id']),
intval($arr['uid'])
);
@@ -1405,7 +1408,7 @@ function event_store_item($arr, $event) {
$item_arr['resource_type'] = 'event';
$item_arr['resource_id'] = $event['event_hash'];
- $item_arr['obj_type'] = ACTIVITY_OBJ_EVENT;
+ $item_arr['obj_type'] = 'Event';
$item_arr['body'] = $prefix . format_event_bbcode($arr);
// if it's local send the permalink to the channel page.
@@ -1414,7 +1417,7 @@ function event_store_item($arr, $event) {
if($wall)
$item_arr['plink'] = $item_arr['mid'];
else
- $item_arr['plink'] = z_root() . '/display/' . gen_link_id($item_arr['mid']);
+ $item_arr['plink'] = z_root() . '/display/' . $item_arr['uuid'];
set_iconfig($item_arr, 'event','timezone',$arr['timezone'],true);
diff --git a/include/feedutils.php b/include/feedutils.php
index a2d52c698..f05c15414 100644
--- a/include/feedutils.php
+++ b/include/feedutils.php
@@ -184,7 +184,7 @@ function construct_verb($item) {
if ($item['verb'])
return $item['verb'];
- return ACTIVITY_POST;
+ return 'Create';
}
function construct_activity_object($item) {
@@ -305,7 +305,7 @@ function get_atom_author($feed, $item) {
}
$rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor');
- if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'], ACTIVITY_OBJ_PERSON)) {
+ if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'], ['Person', ACTIVITY_OBJ_PERSON])) {
$base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
if($base && count($base)) {
foreach($base as $link) {
@@ -350,7 +350,7 @@ function get_atom_author($feed, $item) {
$rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject');
- if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'],ACTIVITY_OBJ_PERSON)) {
+ if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['obj_type'][0]['data'], ['Person', ACTIVITY_OBJ_PERSON])) {
$base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
if($base && count($base)) {
@@ -508,36 +508,17 @@ function get_atom_elements($feed, $item) {
}
}
- $ostatus_protocol = ($ostatus_conversation || (x($res,'verb') && $res['verb']) ? true : false);
-
$mastodon = (($item->get_item_tags('http://mastodon.social/schema/1.0','scope')) ? true : false);
if($mastodon) {
- $ostatus_protocol = true;
if(($mastodon[0]['data']) && ($mastodon[0]['data'] !== 'public'))
$res['item_private'] = 1;
}
- logger('ostatus_protocol: ' . intval($ostatus_protocol), LOGGER_DEBUG);
-
$apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info');
if($apps && $apps[0]['attribs']['']['source']) {
$res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source']));
}
- if($ostatus_protocol) {
-
- // translate OStatus unfollow to activity streams if it happened to get selected
-
- if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) {
- $res['verb'] = ACTIVITY_UNFOLLOW;
- }
-
- // And OStatus 'favorite' is pretty much what we call 'like' on other networks
-
- if((x($res,'verb')) && ($res['verb'] === ACTIVITY_FAVORITE)) {
- $res['verb'] = ACTIVITY_LIKE;
- }
- }
/*
* If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it.
@@ -600,10 +581,7 @@ function get_atom_elements($feed, $item) {
$terms = [];
- if($ostatus_protocol) {
- $res['title'] = '';
- }
- elseif($res['plink'] && $res['title']) {
+ if($res['plink'] && $res['title']) {
$res['body'] = '#^[url=' . $res['plink'] . ']' . $res['title'] . '[/url]' . "\n\n" . $res['body'];
$terms[] = array(
'otype' => TERM_OBJ_POST,
@@ -814,7 +792,7 @@ function get_atom_elements($feed, $item) {
if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE
- && array_key_exists('obj_type',$res) && in_array($res['obj_type'], [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, ACTIVITY_OBJ_ACTIVITY ] )) {
+ && array_key_exists('obj_type',$res) && in_array($res['obj_type'], ['Note', ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT])) {
feed_get_reshare($res,$item);
}
@@ -1197,7 +1175,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// Update content if 'updated' changes
if($r) {
- if(activity_match($datarray['verb'],ACTIVITY_DELETE)
+ if(activity_match($datarray['verb'], ['Delete', ACTIVITY_DELETE])
&& $datarray['author_xchan'] === $r[0]['author_xchan']) {
if(! intval($r[0]['item_deleted'])) {
logger('deleting item ' . $r[0]['id'] . ' mid=' . $datarray['mid'], LOGGER_DEBUG);
@@ -1361,7 +1339,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// allow likes of comments
- if($item_parent_mid && activity_match($datarray['verb'],ACTIVITY_LIKE)) {
+ if($item_parent_mid && activity_match($datarray['verb'], ['Like', ACTIVITY_LIKE])) {
$datarray['thr_parent'] = $item_parent_mid[0]['parent_mid'];
}
@@ -1465,7 +1443,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// Update content if 'updated' changes
if($r) {
- if(isset($datarray['verb']) && activity_match($datarray['verb'], ACTIVITY_DELETE)
+ if(isset($datarray['verb']) && activity_match($datarray['verb'], ['Delete', ACTIVITY_DELETE])
&& isset($datarray['author_xchan']) && $datarray['author_xchan'] === $r[0]['author_xchan']) {
if(! intval($r[0]['item_deleted'])) {
logger('deleting item ' . $r[0]['id'] . ' mid=' . $datarray['mid'], LOGGER_DEBUG);
@@ -1955,7 +1933,7 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
$o .= '<thr:in-reply-to ref="' . xmlify($parent_item) . '" type="text/html" href="' . xmlify($item['plink']) . '" />' . "\r\n";
}
- if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) {
+ if((activity_match($item['obj_type'], ACTIVITY_OBJ_EVENT) || activity_match($item['obj_type'], 'Event')) && activity_match($item['verb'],['Create', ACTIVITY_POST])) {
$obj = ((is_array($item['obj'])) ? $item['obj'] : json_decode($item['obj'],true));
$o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
diff --git a/include/html2bbcode.php b/include/html2bbcode.php
index c928b91b1..03e09cd62 100644
--- a/include/html2bbcode.php
+++ b/include/html2bbcode.php
@@ -10,6 +10,10 @@ Originally made for the syncom project: http://wiki.piratenpartei.de/Syncom
function node2bbcode(&$doc, $oldnode, $attributes, $startbb, $endbb)
{
do {
+ if (empty($startbb) && empty($endbb)) {
+ break;
+ }
+
$done = node2bbcodesub($doc, $oldnode, $attributes, $startbb, $endbb);
} while ($done);
}
@@ -65,6 +69,23 @@ function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
if ($oldNode->hasChildNodes()) {
foreach ($oldNode->childNodes as $child) {
$newNode = $child->cloneNode(true);
+
+ // Newlines are insignificant in HTML, but not so in BBCode, so let's
+ // unwrap the child nodes of when converting them. Also we compress
+ // consecutive whitespace chars to one.
+ //
+ // The exception is `<pre>` and `<code>` elements which
+ // should keep both newlines and whitespace intact.
+ if ($oldNode->nodeName != 'pre' && $oldNode->nodeName != 'code') {
+
+ $newNode->nodeValue = str_replace(
+ array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"),
+ array("<", ">", "<br />", " ", ""),
+ htmlspecialchars($newNode->nodeValue, ENT_COMPAT, 'UTF-8', false));
+
+ $newNode->nodeValue = preg_replace('=[\s]{2,}=i', " ", htmlspecialchars($newNode->nodeValue, ENT_COMPAT, 'UTF-8', false));
+ }
+
$oldNode->parentNode->insertBefore($newNode, $oldNode);
}
}
@@ -104,7 +125,11 @@ function html2bbcode($message)
$message = preg_replace('=<(\w+):(.+?)>=', '<removeme>', $message);
$message = preg_replace('=</(\w+):(.+?)>=', '</removeme>', $message);
- $message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8");
+ // mb_convert_encoding() is deprecated
+ //$message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8");
+ $message = mb_encode_numericentity($message, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
+
+
if(!$message)
return;
@@ -121,16 +146,6 @@ function html2bbcode($message)
deletenode($doc, 'xml');
deletenode($doc, 'removeme');
- $xpath = new DomXPath($doc);
- $list = $xpath->query("//pre");
- foreach ($list as $node)
- $node->nodeValue = str_replace("\n", "\r", $node->nodeValue);
-
- $message = $doc->saveHTML();
- $message = str_replace(array("\n<", ">\n", "\r", "\n", "\xC3\x82\xC2\xA0"), array("<", ">", "<br />", " ", ""), $message);
- $message = preg_replace('= [\s]*=i', " ", $message);
- @$doc->loadHTML($message);
-
node2bbcode($doc, 'html', array(), "", "");
node2bbcode($doc, 'body', array(), "", "");
@@ -172,23 +187,24 @@ function html2bbcode($message)
node2bbcode($doc, 'u', array(), '[u]', '[/u]');
node2bbcode($doc, 's', array(), '[s]', '[/s]');
node2bbcode($doc, 'mark', array(), '[mark]', '[/mark]');
+ node2bbcode($doc, 'span', array(), "", "");
node2bbcode($doc, 'big', array(), "[size=large]", "[/size]");
node2bbcode($doc, 'small', array(), "[size=small]", "[/size]");
- node2bbcode($doc, 'blockquote', array(), '[quote]', '[/quote]');
+ // Use a temporary tag to keep line breaks
+ node2bbcode($doc, 'br', array(), '[br]', '');
- node2bbcode($doc, 'br', array(), "\n", '');
+ node2bbcode($doc, 'a', array('href'=>'/(.+)/'), '[url=$1]', '[/url]');
- node2bbcode($doc, 'p', array('class'=>'MsoNormal'), "\n", "");
- node2bbcode($doc, 'div', array('class'=>'MsoNormal'), "\r", "");
+ node2bbcode($doc, 'img', array('src'=>'/(.+)/', 'width'=>'/(\d+)/', 'height'=>'/(\d+)/'), '[img=$2x$3]$1', '[/img]');
+ node2bbcode($doc, 'img', array('src'=>'/(.+)/', 'alt'=>'/(.+)/'), '[img=$1]$2', '[/img]');
+ node2bbcode($doc, 'img', array('src'=>'/(.+)/'), '[img]$1', '[/img]');
- node2bbcode($doc, 'span', array(), "", "");
+ node2bbcode($doc, 'video', array('src'=>'/(.+)/'), '[video]$1', '[/video]');
+ node2bbcode($doc, 'audio', array('src'=>'/(.+)/'), '[audio]$1', '[/audio]');
+// node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]');
- node2bbcode($doc, 'span', array(), "", "");
- node2bbcode($doc, 'pre', array(), "", "");
- node2bbcode($doc, 'div', array(), "\r", "\r");
- node2bbcode($doc, 'p', array(), "\n", "\n");
node2bbcode($doc, 'ul', array(), "[list]", "[/list]");
node2bbcode($doc, 'ol', array(), "[list=1]", "[/list]");
@@ -205,24 +221,25 @@ function html2bbcode($message)
node2bbcode($doc, 'tr', array(), "[tr]", "[/tr]");
node2bbcode($doc, 'td', array(), "[td]", "[/td]");
- node2bbcode($doc, 'h1', array(), "\n\n[h1]", "[/h1]\n");
- node2bbcode($doc, 'h2', array(), "\n\n[h2]", "[/h2]\n");
- node2bbcode($doc, 'h3', array(), "\n\n[h3]", "[/h3]\n");
- node2bbcode($doc, 'h4', array(), "\n\n[h4]", "[/h4]\n");
- node2bbcode($doc, 'h5', array(), "\n\n[h5]", "[/h5]\n");
- node2bbcode($doc, 'h6', array(), "\n\n[h6]", "[/h6]\n");
+ node2bbcode($doc, 'h1', array(), "[h1]", "[/h1]");
+ node2bbcode($doc, 'h2', array(), "[h2]", "[/h2]");
+ node2bbcode($doc, 'h3', array(), "[h3]", "[/h3]");
+ node2bbcode($doc, 'h4', array(), "[h4]", "[/h4]");
+ node2bbcode($doc, 'h5', array(), "[h5]", "[/h5]");
+ node2bbcode($doc, 'h6', array(), "[h6]", "[/h6]");
- node2bbcode($doc, 'a', array('href'=>'/(.+)/'), '[url=$1]', '[/url]');
- node2bbcode($doc, 'img', array('src'=>'/(.+)/', 'width'=>'/(\d+)/', 'height'=>'/(\d+)/'), '[img=$2x$3]$1', '[/img]');
- node2bbcode($doc, 'img', array('src'=>'/(.+)/'), '[img]$1', '[/img]');
+ node2bbcode($doc, 'blockquote', array(), '[quote]', '[/quote]');
+ node2bbcode($doc, 'pre', array(), "", "");
+ node2bbcode($doc, 'code', array('class'=>'/(.+)/'), '[code=$1]', '[/code]');
+ node2bbcode($doc, 'code', array(), '[code]', '[/code]');
- node2bbcode($doc, 'video', array('src'=>'/(.+)/'), '[video]$1', '[/video]');
- node2bbcode($doc, 'audio', array('src'=>'/(.+)/'), '[audio]$1', '[/audio]');
-// node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]');
+ node2bbcode($doc, 'p', array('class'=>'MsoNormal'), "\n", "");
+ node2bbcode($doc, 'p', array(), "\n", "\n");
- node2bbcode($doc, 'code', array(), '[code]', '[/code]');
+ node2bbcode($doc, 'div', array('class'=>'MsoNormal'), "\r", "");
+ node2bbcode($doc, 'div', array(), "\r", "\r");
$message = $doc->saveHTML();
@@ -263,6 +280,8 @@ function html2bbcode($message)
$oldmessage = $message;
$message = str_replace(array(
"[/size]\n\n",
+ "\n[br]",
+ "[br]\n",
"\n[hr]",
"[hr]\n",
"\n[list",
@@ -273,6 +292,8 @@ function html2bbcode($message)
"\n[*]"),
array(
"[/size]\n",
+ "[br]",
+ "[br]",
"[hr]",
"[hr]",
"[list",
@@ -287,6 +308,9 @@ function html2bbcode($message)
$message = str_replace(array('[b][b]', '[/b][/b]', '[i][i]', '[/i][/i]'),
array('[b]', '[/b]', '[i]', '[/i]'), $message);
+ // Restore linebreaks from temp tag
+ $message = preg_replace('/\[br\]\s?/', "\n", $message);
+
// Handling Yahoo style of mails
// $message = str_replace('[hr][b]From:[/b]', '[quote][b]From:[/b]', $message);
diff --git a/include/html2plain.php b/include/html2plain.php
index 48bbe3d9e..5cb7ee35d 100644
--- a/include/html2plain.php
+++ b/include/html2plain.php
@@ -121,7 +121,10 @@ function html2plain($html, $wraplength = 75, $compact = false)
{
$message = str_replace("\r", "", $html);
- $message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8");
+
+ // mb_convert_encoding() is deprecated
+ //$message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8");
+ $message = mb_encode_numericentity($message, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
if(!$message)
return;
diff --git a/include/import.php b/include/import.php
index 291dd2638..7dac518f5 100644
--- a/include/import.php
+++ b/include/import.php
@@ -80,6 +80,12 @@ function import_channel($channel, $account_id, $seize, $newname = '') {
}
}
+ if (empty($channel['channel_epubkey']) && empty($channel['channel_eprvkey'])) {
+ $eckey = sodium_crypto_sign_keypair();
+ $channel['channel_epubkey'] = sodium_bin2base64(sodium_crypto_sign_publickey($eckey), SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
+ $channel['channel_eprvkey'] = sodium_bin2base64(sodium_crypto_sign_secretkey($eckey), SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING);
+ }
+
unset($channel['channel_id']);
$channel['channel_account_id'] = $account_id;
$channel['channel_primary'] = (($seize) ? 1 : 0);
diff --git a/include/items.php b/include/items.php
index 6cef3d2cd..a5a23650e 100644
--- a/include/items.php
+++ b/include/items.php
@@ -353,7 +353,7 @@ function can_comment_on_post($observer_xchan, $item) {
case 'specific':
case 'contacts':
case '':
- if(local_channel() && get_abconfig(local_channel(), (($item['verb'] === ACTIVITY_SHARE) ? $item['author_xchan'] : $item['owner_xchan']), 'their_perms', 'post_comments')) {
+ if(local_channel() && get_abconfig(local_channel(), (($item['verb'] === ACTIVITY_SHARE) ? $item['source_xchan'] : $item['owner_xchan']), 'their_perms', 'post_comments')) {
return true;
}
if(intval($item['item_wall']) && perm_is_allowed($item['uid'],$observer_xchan,'post_comments')) {
@@ -459,7 +459,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
if(! $arr['mid']) {
- $arr['uuid'] = ((x($arr,'uuid')) ? $arr['uuid'] : item_message_id());
+ $arr['uuid'] = ((x($arr,'uuid')) ? $arr['uuid'] : new_uuid());
}
$arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : z_root() . '/item/' . $arr['uuid']);
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? $arr['parent_mid'] : $arr['mid']);
@@ -468,10 +468,8 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
$arr['owner_xchan'] = ((x($arr,'owner_xchan')) ? $arr['owner_xchan'] : $channel['channel_hash']);
$arr['author_xchan'] = ((x($arr,'author_xchan')) ? $arr['author_xchan'] : $observer['xchan_hash']);
- $arr['verb'] = ((x($arr,'verb')) ? $arr['verb'] : ACTIVITY_POST);
- $arr['obj_type'] = ((x($arr,'obj_type')) ? $arr['obj_type'] : ACTIVITY_OBJ_NOTE);
- if(($is_comment) && ($arr['obj_type'] === ACTIVITY_OBJ_NOTE))
- $arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
+ $arr['verb'] = ((x($arr,'verb')) ? $arr['verb'] : 'Create');
+ $arr['obj_type'] = ((x($arr,'obj_type')) ? $arr['obj_type'] : 'Note');
if(! ( array_key_exists('allow_cid',$arr) || array_key_exists('allow_gid',$arr)
|| array_key_exists('deny_cid',$arr) || array_key_exists('deny_gid',$arr))) {
@@ -522,7 +520,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
return $ret;
if($post_id && $deliver) {
- Master::Summon([ 'Notifier','activity',$post_id ]);
+ Master::Summon(['Notifier','activity', $post_id]);
}
$ret['success'] = true;
@@ -1751,8 +1749,8 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : '');
$arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : '');
$arr['thr_parent'] = ((x($arr,'thr_parent')) ? notags(trim($arr['thr_parent'])) : $arr['parent_mid']);
- $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : ACTIVITY_POST);
- $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : ACTIVITY_OBJ_NOTE);
+ $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : 'Create');
+ $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : 'Note');
$arr['obj'] = ((x($arr,'obj')) ? trim($arr['obj']) : '');
$arr['tgt_type'] = ((x($arr,'tgt_type')) ? notags(trim($arr['tgt_type'])) : '');
$arr['target'] = ((x($arr,'target')) ? trim($arr['target']) : '');
@@ -1775,13 +1773,18 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$d1 = new DateTime('now +10 minutes', new DateTimeZone('UTC'));
$d2 = new DateTime($arr['created'] . '+00:00');
- if($d2 > $d1)
+
+ if($d2 > $d1) {
$arr['item_delayed'] = 1;
+ }
- $arr['llink'] = z_root() . '/display/' . gen_link_id($arr['mid']);
+ if(empty($arr['llink'])) {
+ $arr['llink'] = z_root() . '/display/' . $arr['uuid'];
+ }
- if(! $arr['plink'])
+ if(empty($arr['plink'])) {
$arr['plink'] = $arr['llink'];
+ }
if($arr['parent_mid'] === $arr['mid']) {
$parent_id = 0;
@@ -1822,9 +1825,6 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
return $ret;
}
- if(($arr['obj_type'] == ACTIVITY_OBJ_NOTE) && (! $arr['obj']))
- $arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
-
// is the new message multi-level threaded?
// even though we don't support it now, preserve the info
// and re-attach to the conversation parent.
@@ -1837,7 +1837,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
dbesc($r[0]['parent_mid']),
intval($arr['uid'])
);
- if($z && count($z))
+ if($z)
$r = $z;
}
@@ -1999,14 +1999,15 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
if(($terms) && (is_array($terms))) {
foreach($terms as $t) {
- q("insert into term (uid,oid,otype,ttype,term,url)
- values(%d,%d,%d,%d,'%s','%s') ",
+ q("insert into term (uid,oid,otype,ttype,term,url,imgurl)
+ values(%d,%d,%d,%d,'%s','%s','%s') ",
intval($arr['uid']),
intval($current_post),
intval(TERM_OBJ_POST),
intval($t['ttype']),
dbesc($t['term']),
- dbesc($t['url'])
+ dbesc($t['url']),
+ dbesc($t['imgurl'] ?? ''),
);
}
@@ -2443,7 +2444,7 @@ function send_status_notifications($post_id,$item) {
$type = ((intval($item['item_private']) === 2) ? NOTIFY_MAIL : NOTIFY_COMMENT);
- if(array_key_exists('verb',$item) && (activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE))) {
+ if(array_key_exists('verb',$item) && activity_match($item['verb'], ['Like', 'Dislike', ACTIVITY_LIKE, ACTIVITY_DISLIKE])) {
$type = NOTIFY_LIKE;
@@ -2487,8 +2488,8 @@ function send_status_notifications($post_id,$item) {
// check for an unfollow thread activity - we should probably decode the obj and check the id
// but it will be extremely rare for this to be wrong.
- if(($xx['verb'] === ACTIVITY_UNFOLLOW)
- && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO)
+ if((in_array($xx['verb'], ['Ignore', ACTIVITY_UNFOLLOW]))
+ && (in_array($xx['obj_type'], ['Note', 'Image', ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_PHOTO]))
&& ($xx['parent'] != $xx['id']))
$unfollowed = true;
}
@@ -2501,7 +2502,7 @@ function send_status_notifications($post_id,$item) {
if($unfollowed)
return;
- $link = z_root() . '/display/' . gen_link_id($item['mid']);
+ $link = z_root() . '/display/' . $item['uuid'];
$y = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($link),
@@ -2514,7 +2515,6 @@ function send_status_notifications($post_id,$item) {
if(! $notify)
return;
-
Enotify::submit(array(
'type' => $type,
'from_xchan' => $item['author_xchan'],
@@ -2607,7 +2607,6 @@ function tag_deliver($uid, $item_id) {
return;
}
-
if ($is_group && intval($item['item_thread_top']) && intval($item['item_wall']) && $item['author_xchan'] !== $item['owner_xchan']) {
if($item['resource_type'] === 'group_item') {
@@ -2625,39 +2624,6 @@ function tag_deliver($uid, $item_id) {
}
/*
- * Seems like a good place to plug in a poke notification.
- */
-
- if (stristr($item['verb'],ACTIVITY_POKE)) {
- $poke_notify = true;
-
- if(($item['obj_type'] == "") || ($item['obj_type'] !== ACTIVITY_OBJ_PERSON) || (! $item['obj']))
- $poke_notify = false;
-
- $obj = json_decode($item['obj'],true);
- if($obj) {
- if($obj['id'] !== $u[0]['channel_hash'])
- $poke_notify = false;
- }
- if(intval($item['item_deleted']))
- $poke_notify = false;
-
- $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1));
- if($poke_notify) {
- Enotify::submit(array(
- 'to_xchan' => $u[0]['channel_hash'],
- 'from_xchan' => $item['author_xchan'],
- 'type' => NOTIFY_POKE,
- 'item' => $item,
- 'link' => $i[0]['llink'],
- 'verb' => ACTIVITY_POKE,
- 'activity' => $verb,
- 'otype' => 'item'
- ));
- }
- }
-
- /*
* Do community tagging
*/
@@ -3174,7 +3140,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
$item['mid'] = z_root() . '/item/' . $item['uuid'];
$item['parent_mid'] = $item['mid'];
$item['thr_parent'] = $item['mid'];
- $item['llink'] = z_root() . '/display/' . gen_link_id($item['mid']);
+ $item['llink'] = z_root() . '/display/' . $item['uuid'];
}
$r = q("UPDATE item SET author_xchan = '%s', mid = '%s', parent_mid = '%s', thr_parent = '%s', llink = '%s' WHERE id = %d",
@@ -3297,7 +3263,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
$arr['owner_xchan'] = $channel['channel_hash'];
$arr['obj_type'] = $item['obj_type'];
- $arr['verb'] = ACTIVITY_POST;
+ $arr['verb'] = 'Create';
$arr['allow_cid'] = $channel['channel_allow_cid'];
$arr['allow_gid'] = $channel['channel_allow_gid'];
@@ -4411,7 +4377,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
$item_normal = item_normal();
if (! (isset($arr['include_follow']) && intval($arr['include_follow']))) {
- $item_normal .= sprintf(" and not verb in ('%s', '%s') ",
+ $item_normal .= sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ",
dbesc(ACTIVITY_FOLLOW),
dbesc(ACTIVITY_UNFOLLOW)
);
@@ -4824,54 +4790,7 @@ function comment_local_origin($item) {
return false;
}
-
-
-function send_profile_photo_activity($channel,$photo,$profile) {
-
- // for now only create activities for the default profile
-
- if(! intval($profile['is_default']))
- return;
-
- $arr = array();
- $arr['item_thread_top'] = 1;
- $arr['item_origin'] = 1;
- $arr['item_wall'] = 1;
-
- if(stripos($profile['gender'],t('female')) !== false)
- $t = t('%1$s updated her %2$s');
- elseif(stripos($profile['gender'],t('male')) !== false)
- $t = t('%1$s updated his %2$s');
- else
- $t = t('%1$s updated their %2$s');
-
- $ptext = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']' . t('profile photo') . '[/zrl]';
-
- $ltext = '[zrl=' . z_root() . '/profile/' . $channel['channel_address'] . ']' . '[zmg=150x150]' . z_root() . '/photo/' . $photo['resource_id'] . '-4[/zmg][/zrl]';
-
- $arr['body'] = sprintf($t,$channel['channel_name'],$ptext) . "\n\n" . $ltext;
-
- $acl = new Zotlabs\Access\AccessList($channel);
- $x = $acl->get();
-
- $arr['allow_cid'] = $x['allow_cid'];
-
- $arr['allow_gid'] = $x['allow_gid'];
- $arr['deny_cid'] = $x['deny_cid'];
- $arr['deny_gid'] = $x['deny_gid'];
-
- $arr['uid'] = $channel['channel_id'];
- $arr['aid'] = $channel['channel_account_id'];
-
- $arr['owner_xchan'] = $channel['channel_hash'];
- $arr['author_xchan'] = $channel['channel_hash'];
-
- post_activity_item($arr);
-}
-
-
function sync_an_item($channel_id,$item_id) {
-
$r = q("select * from item where id = %d",
intval($item_id)
);
@@ -5151,83 +5070,13 @@ function fix_attached_permissions($uid, $body, $str_contact_allow, $str_group_al
}
}
-function item_create_edit_activity($post) {
-
- if((! $post) || (! $post['item']) || ($post['item']['item_type'] != ITEM_TYPE_POST))
- return;
-
- $update_item = $post['item'];
-
- $new_item = $update_item;
-
- $author = q("select * from xchan where xchan_hash = '%s' limit 1",
- dbesc($new_item['author_xchan'])
- );
- if($author)
- $item_author = $author[0];
-
-
- $new_item['id'] = 0;
- $new_item['parent'] = 0;
- $new_item['uuid'] = item_message_id();
- $new_item['mid'] = z_root() . '/item/' . $new_item['uuid'];
-
- $new_item['body'] = sprintf( t('[Edited %s]'), (($update_item['item_thread_top']) ? t('Post','edit_activity') : t('Comment','edit_activity')));
-
- $new_item['body'] .= "\n\n";
- $new_item['body'] .= $update_item['body'];
-
- $new_item['sig'] = '';
-
- $new_item['verb'] = ACTIVITY_UPDATE;
- $new_item['item_thread_top'] = 0;
- $new_item['created'] = $new_item['edited'] = datetime_convert();
- $new_item['obj_type'] = (($update_item['item_thread_top']) ? ACTIVITY_OBJ_NOTE : ACTIVITY_OBJ_COMMENT);
- $new_item['obj'] = json_encode(array(
- 'type' => $new_item['obj_type'],
- 'id' => $update_item['mid'],
- 'parent' => $update_item['parent_mid'],
- 'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $update_item['plink'])),
- 'title' => $update_item['title'],
- 'content' => $update_item['body'],
- 'created' => $update_item['created'],
- 'edited' => $update_item['edited'],
- 'author' => array(
- 'name' => $item_author['xchan_name'],
- 'address' => $item_author['xchan_addr'],
- 'guid' => $item_author['xchan_guid'],
- 'guid_sig' => $item_author['xchan_guid_sig'],
- 'link' => array(
- array('rel' => 'alternate', 'type' => 'text/html', 'href' => $item_author['xchan_url']),
- array('rel' => 'photo', 'type' => $item_author['xchan_photo_mimetype'], 'href' => $item_author['xchan_photo_m'])),
- ),
- ));
-
-
- $x = post_activity_item($new_item);
- $post_id = $x['id'];
- if($post_id) {
- $r = q("select * from item where id = %d",
- intval($post_id)
- );
- if($r) {
- xchan_query($r);
- $sync_item = fetch_post_tags($r);
- Libsync::build_sync_packet($new_item['uid'],array('item' => array(encode_item($sync_item[0],true))));
- }
- }
-
- Master::Summon([ 'Notifier', 'edit_activity', $post_id ]);
-}
/**
* @brief copies an entire conversation from the pubstream to this channel's stream
* which will allow you to interact with it.
*/
-
-
function copy_of_pubitem($channel,$mid) {
$result = null;
diff --git a/include/markdown.php b/include/markdown.php
index 7fba1259f..b2adcd0d5 100644
--- a/include/markdown.php
+++ b/include/markdown.php
@@ -221,6 +221,21 @@ function bb_to_markdown_transform_tags($match) {
return '#'. str_replace(' ', '_', $match[3]);
}
+function bb_to_markdown_parse_b64_crypt($match) {
+
+ if(empty($match[1])) {
+ return;
+ }
+
+ $r = '```' . "\n";
+ $r .= '-----BEGIN ENCRYPTED MESSAGE-----' . "\n";
+ $r .= $match[1] . "\n";
+ $r .= '-----END ENCRYPTED MESSAGE-----' . "\n";
+ $r .= '```' . "\n";
+
+ return wordwrap($r, 75, "\n", true);
+
+}
/**
* @brief Convert bbcode to Markdown.
@@ -244,6 +259,10 @@ function bb_to_markdown($Text, $options = []) {
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_to_markdown_share', $Text);
+ if (str_contains($Text, '[/crypt]')) {
+ $Text = preg_replace_callback("/\[crypt\](.*?)\[\/crypt\]/ism", 'bb_to_markdown_parse_b64_crypt', $Text);
+ }
+
$x = [ 'bbcode' => $Text, 'options' => $options ];
/**
@@ -264,8 +283,8 @@ function bb_to_markdown($Text, $options = []) {
// Now convert HTML to Markdown
$Text = html2markdown($Text);
- //html2markdown adds backslashes infront of hashes after a new line. remove them
- $Text = str_replace("\n\#", "\n#", $Text);
+ //html2markdown adds backslashes infront of hashes and dashes after a new line. remove them
+ $Text = str_replace(["\n\#", "\n\-----"], ["\n#", "\n-----"], $Text);
// If the text going into bbcode() has a plain URL in it, i.e.
// with no [url] tags around it, it will come out of parseString()
diff --git a/include/network.php b/include/network.php
index dee11e3e9..a5c14f9d1 100644
--- a/include/network.php
+++ b/include/network.php
@@ -1,6 +1,6 @@
<?php
-use Zotlabs\Lib\LDSignatures;
+use Zotlabs\Lib\Activity;
use Zotlabs\Lib\Zotfinger;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\Queue;
@@ -423,25 +423,20 @@ function json_return_and_die($x, $content_type = 'application/json') {
killme();
}
-function as_return_and_die($obj,$channel) {
+function as_return_and_die($obj, $channel = []) {
- $x = array_merge(['@context' => [
- ACTIVITYSTREAMS_JSONLD_REV,
- 'https://w3id.org/security/v1',
- z_root() . ZOT_APSCHEMA_REV
- ]], $obj );
+ $ret = Activity::build_packet($obj, $channel);
+ logger('data: ' . jindent($ret), LOGGER_DATA);
- $headers = [];
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
- $x['signature'] = LDSignatures::sign($x,$channel);
- $ret = json_encode($x, JSON_UNESCAPED_SLASHES);
- logger('data: ' . jindent($ret), LOGGER_DATA);
$headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T');
$headers['Digest'] = HTTPSig::generate_digest_header($ret);
$headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI'];
- $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel));
- HTTPSig::set_headers($h);
+ if ($channel) {
+ $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel));
+ HTTPSig::set_headers($h);
+ }
echo $ret;
killme();
@@ -598,23 +593,30 @@ function validate_url(&$url) {
}
/**
- * @brief Checks that email is an actual resolvable internet address.
+ * @brief Checks that email is valid, and that the domain resolves.
*
- * @param string $addr
- * @return boolean
+ * Note: This does not try to check that the actual email address will resolve,
+ * only the domain!
+ *
+ * @param string $addr The email address to validate.
+ * @return boolean True if email is valid, false otherwise.
*/
-function validate_email($addr) {
+function validate_email(string $addr): bool {
if(get_config('system', 'disable_email_validation'))
return true;
- if(! strpos($addr, '@'))
- return false;
-
- $h = substr($addr, strpos($addr, '@') + 1);
+ $matches = array();
+ $result = preg_match(
+ '/^[A-Z0-9._%-]+@([A-Z0-9.-]+\.[A-Z0-9-]{2,})$/i',
+ punify($addr),
+ $matches);
- if(($h) && z_dns_check($h, true)) {
- return true;
+ if($result) {
+ $domain = $matches[1];
+ if(($domain) && z_dns_check($domain, true)) {
+ return true;
+ }
}
return false;
@@ -2138,12 +2140,13 @@ function get_request_string($url) {
}
-/*
+/**
+ * Builds a url from the result of `parse_url`.
*
- * Takes the output of parse_url and builds a URL from it
+ * @param array $parsed_url An associative array as produced by `parse_url`.
*
+ * @return The reassembled URL as a string.
*/
-
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
diff --git a/include/oembed.php b/include/oembed.php
index fbe6a573b..a90c91641 100644
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -395,7 +395,11 @@ function oembed_format_object($j){
$ret .= "<br /><a href='$embedurl' rel='oembed'>$embedurl</a>";
}
$ret.="<br style='clear:left'></span>";
- return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret));
+
+ // mb_convert_encoding() is deprecated
+ // return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret));
+ return mb_encode_numericentity($ret, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
+
}
function oembed_iframe($src,$width,$height) {
@@ -456,7 +460,10 @@ function oembed_html2bbcode($text) {
if (strpos($text, "oembed")){
// convert non ascii chars to html entities
- $html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text));
+
+ // mb_convert_encoding() is deprecated
+ // $html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text));
+ $html_text = mb_encode_numericentity($text, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
// If it doesn't parse at all, just return the text.
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index 522e638de..4394d3238 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -117,7 +117,14 @@ function guess_image_type($filename, $data = '') {
$body = $data['body'];
if ($body) {
$image = new Imagick();
- $image->readImageBlob($body);
+
+ try{
+ $image->readImageBlob($body);
+ } catch (\Exception $e) {
+ logger('Imagick readImageBlob() exception:' . print_r($e, true));
+ return $type;
+ }
+
$r = $image->identifyImage();
if ($r && is_array($r) && array_key_exists($r['mimetype'], $types))
$type = $r['mimetype'];
diff --git a/include/photos.php b/include/photos.php
index 8d83b8475..5e993e15f 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -455,7 +455,7 @@ function photo_upload($channel, $observer, $args) {
$item['body'] = $summary;
$item['mimetype'] = 'text/bbcode';
- $item['obj_type'] = ACTIVITY_OBJ_PHOTO;
+ $item['obj_type'] = 'Image';
$object['id'] = $item['mid'];
$object['diaspora:guid'] = $item['uuid'];
@@ -511,8 +511,8 @@ function photo_upload($channel, $observer, $args) {
'allow_gid' => $ac['allow_gid'],
'deny_cid' => $ac['deny_cid'],
'deny_gid' => $ac['deny_gid'],
- 'verb' => ACTIVITY_POST,
- 'obj_type' => ACTIVITY_OBJ_PHOTO,
+ 'verb' => 'Create',
+ 'obj_type' => 'Image',
'obj' => json_encode($object),
'tgt_type' => 'orderedCollection',
'target' => json_encode($target),
diff --git a/include/plugin.php b/include/plugin.php
index 2a35b72de..bbfeab988 100644
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -213,7 +213,7 @@ function reload_plugins() {
if(function_exists($pl . '_unload')) {
$func = $pl . '_unload';
try {
- $func();
+ $func();
} catch (Exception $e) {
handleerrors_plugin($pl, '', 'UNLOAD FAILED (uninstalling) : ' . $e->getMessage(),true);
continue;
@@ -222,7 +222,7 @@ function reload_plugins() {
if(function_exists($pl . '_load')) {
$func = $pl . '_load';
try {
- $func();
+ $func();
} catch (Exception $e) {
handleerrors_plugin($pl, '', 'LOAD FAILED (uninstalling): ' . $e->getMessage(),true);
continue;
@@ -556,7 +556,11 @@ function get_plugin_info($plugin){
$ll = explode("\n", $m[0]);
foreach( $ll as $l ) {
$l = trim($l, "\t\n\r */");
- if ($l != ""){
+ if ($l != "") {
+ if (strpos($l, ':') === false) {
+ continue;
+ }
+
list($k, $v) = array_map("trim", explode(":", $l, 2));
$k = strtolower($k);
if ($k == 'author' || $k == 'maintainer'){
@@ -643,7 +647,11 @@ function get_widget_info($widget){
$ll = explode("\n", $m[0]);
foreach( $ll as $l ) {
$l = trim($l, "\t\n\r */");
- if ($l != ""){
+ if ($l != "") {
+ if (strpos($l, ':') === false) {
+ continue;
+ }
+
list($k, $v) = array_map("trim", explode(":", $l, 2));
$k = strtolower($k);
if ($k == 'author' || $k == 'maintainer'){
@@ -778,7 +786,11 @@ function get_theme_info($theme){
$ll = explode("\n", $m[0]);
foreach( $ll as $l ) {
$l = trim($l, "\t\n\r */");
- if ($l != ""){
+ if ($l != "") {
+ if (strpos($l, ':') === false) {
+ continue;
+ }
+
list($k, $v) = array_map("trim", explode(":", $l, 2));
$k = strtolower($k);
if ($k == 'author'){
@@ -860,7 +872,7 @@ function get_template_info($template){
$ll = explode("\n", $m[0]);
foreach( $ll as $l ) {
$l = trim($l, "\t\n\r */");
- if ($l != ""){
+ if ($l != "") {
if (strpos($l, ':') === false) {
continue;
}
@@ -973,12 +985,12 @@ function format_css_if_exists($source) {
}
} else {
// It's a file from the theme
- $path = '/' . theme_include($script);
+ $path = theme_include($script);
}
if($path) {
$qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION;
- return '<link rel="stylesheet" href="' . $path_prefix . $path . $qstring . '" type="text/css" media="' . $source[1] . '">' . "\r\n";
+ return '<link rel="stylesheet" href="' . $path_prefix . '/' . $path . $qstring . '" type="text/css" media="' . $source[1] . '">' . "\r\n";
}
}
@@ -1045,11 +1057,11 @@ function format_js_if_exists($source) {
}
else {
// It's a file from the theme
- $path = '/' . theme_include($source);
+ $path = theme_include($source);
}
if($path) {
$qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION;
- return '<script src="' . $path_prefix . $path . $qstring . '" ></script>' . "\r\n" ;
+ return '<script src="' . $path_prefix . '/' . $path . $qstring . '" ></script>' . "\r\n" ;
}
}
diff --git a/include/sharedwithme.php b/include/sharedwithme.php
deleted file mode 100644
index b342f51d5..000000000
--- a/include/sharedwithme.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-function apply_updates() {
-
- //check for updated items and remove them
- $x = q("SELECT mid, max(obj) AS obj FROM item WHERE verb = '%s' AND obj_type = '%s' GROUP BY mid",
- dbesc(ACTIVITY_UPDATE),
- dbesc(ACTIVITY_OBJ_FILE)
- );
-
- if($x) {
-
- foreach($x as $xx) {
-
- $object = json_decode($xx['obj'],true);
-
- $d_mid = $object['d_mid'];
- $u_mid = $xx['mid'];
-
- $y = q("DELETE FROM item WHERE obj_type = '%s' AND (verb = '%s' AND mid = '%s') OR (verb = '%s' AND mid = '%s')",
- dbesc(ACTIVITY_OBJ_FILE),
- dbesc(ACTIVITY_POST),
- dbesc($d_mid),
- dbesc(ACTIVITY_UPDATE),
- dbesc($u_mid)
- );
-
- }
-
- }
-
-}
diff --git a/include/taxonomy.php b/include/taxonomy.php
index cfec8414a..90ccb6142 100644
--- a/include/taxonomy.php
+++ b/include/taxonomy.php
@@ -58,7 +58,7 @@ function term_item_parent_query($uid,$table,$s,$type = TERM_UNKNOWN, $type2 = ''
$s = str_replace('*','%',$s);
if($type2) {
- $r = q("select parent from item left join term on term.oid = item.id where term.ttype in (%d, %d) and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'",
+ $r = q("select parent from item left join term on term.oid = item.id where term.ttype in (%d, %d) and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb NOT IN ('Update', '%s')",
intval($type),
intval($type2),
dbesc($s),
@@ -67,7 +67,7 @@ function term_item_parent_query($uid,$table,$s,$type = TERM_UNKNOWN, $type2 = ''
);
}
else {
- $r = q("select parent from item left join term on term.oid = item.id where term.ttype = %d and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb != '%s'",
+ $r = q("select parent from item left join term on term.oid = item.id where term.ttype = %d and term.term like '%s' and term.uid = %d and term.otype = 1 and item.verb NOT IN ('Update', '%s')",
intval($type),
dbesc($s),
intval($uid),
diff --git a/include/text.php b/include/text.php
index fc30ed8aa..713911af2 100644
--- a/include/text.php
+++ b/include/text.php
@@ -13,6 +13,7 @@ use Zotlabs\Lib\Crypto;
use Zotlabs\Lib\SvgSanitizer;
use Zotlabs\Lib\Libzot;
use Zotlabs\Lib\AccessList;
+use Zotlabs\Lib\Text;
require_once("include/bbcode.php");
@@ -108,10 +109,14 @@ function notags($string) {
* @return string
*/
function escape_tags($string) {
+ return Text::escape_tags($string);
+}
+
+function unescape_tags($string) {
if (!$string) {
return EMPTY_STR;
}
- return (htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false));
+ return (htmlspecialchars_decode($string, ENT_COMPAT));
}
/**
@@ -267,31 +272,41 @@ function purify_html($s, $allow_position = false) {
//data- attributes used by the bootstrap library
- $def->info_global_attr['data-dismiss'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-target'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-toggle'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-backdrop'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-keyboard'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-show'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-spy'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-offset'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-animation'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-container'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-delay'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-placement'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-title'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-trigger'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-content'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-trigger'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-parent'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-ride'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-slide-to'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-slide'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-interval'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-pause'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-wrap'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-offset-top'] = new HTMLPurifier_AttrDef_Text;
- $def->info_global_attr['data-offset-bottom'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-target'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-ride'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-slide'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-toggle'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-animation'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-title'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-delay'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-parent'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-offset'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-dismiss'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-backdrop'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-keyboard'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-content'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-container'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-trigger'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-spy'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-placement'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-slide-to'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-interval'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-pause'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-wrap'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-display'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-root-margin'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-smooth-scroll'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-dismiss'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-delay'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-autohide'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-scroll'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-reference'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-config'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-custom-class'] = new HTMLPurifier_AttrDef_Text;
+ //old
+ $def->info_global_attr['data-bs-show'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-offset-top'] = new HTMLPurifier_AttrDef_Text;
+ $def->info_global_attr['data-bs-offset-bottom'] = new HTMLPurifier_AttrDef_Text;
//some html5 elements
//Block
@@ -1253,76 +1268,32 @@ function sslify($s) {
return $s;
}
-/**
- * @brief Get an array of poke verbs.
- *
- * @return array
- * * \e index is present tense verb
- * * \e value is array containing past tense verb, translation of present, translation of past
- */
-function get_poke_verbs() {
-
- $arr = [
- 'poke' => ['poked', t('poke'), t('poked')],
- 'ping' => ['pinged', t('ping'), t('pinged')],
-
- // Those might be better suited for a nsfw poke addon
-
- // 'prod' => ['prodded', t('prod'), t('prodded')],
- // 'slap' => ['slapped', t('slap'), t('slapped')],
- // 'finger' => ['fingered', t('finger'), t('fingered')],
- // 'rebuff' => ['rebuffed', t('rebuff'), t('rebuffed')]
+function get_emojis() {
+ $emojis = [
+ // Reactions (emojitwo emojis)
+ 'astonished_face' => ['shortname' => ':astonished_face:', 'filepath' => 'images/emoji/astonished_face.png'],
+ 'bottle_with_popping_cork' => ['shortname' => ':bottle_with_popping_cork:', 'filepath' => 'images/emoji/bottle_with_popping_cork.png'],
+ 'clapping_hands' => ['shortname' => ':clapping_hands:', 'filepath' => 'images/emoji/clapping_hands.png'],
+ 'disappointed_face' => ['shortname' => ':disappointed_face:', 'filepath' => 'images/emoji/disappointed_face.png'],
+ 'grinning_face' => ['shortname' => ':grinning_face:', 'filepath' => 'images/emoji/grinning_face.png'],
+ 'kiss_mark' => ['shortname' => ':kiss_mark:', 'filepath' => 'images/emoji/kiss_mark.png'],
+ 'red_heart' => ['shortname' => ':red_heart:', 'filepath' => 'images/emoji/red_heart.png'],
+ 'sleeping_face' => ['shortname' => ':sleeping_face:', 'filepath' => 'images/emoji/sleeping_face.png'],
+ 'slightly_smiling_face' => ['shortname' => ':slightly_smiling_face:', 'filepath' => 'images/emoji/slightly_smiling_face.png'],
+ 'smiling_face_with_halo' => ['shortname' => ':smiling_face_with_halo:', 'filepath' => 'images/emoji/smiling_face_with_halo.png'],
+ 'smiling_face_with_horns' => ['shortname' => ':smiling_face_with_horns:', 'filepath' => 'images/emoji/smiling_face_with_horns.png'],
+ 'winking_face_with_tongue' => ['shortname' => ':winking_face_with_tongue:', 'filepath' => 'images/emoji/winking_face_with_tongue.png'],
+
+ 'facepalm' => ['shortname' => ':facepalm:', 'filepath' => 'images/emoticons/smiley-facepalm.gif']
];
- /**
- * @hooks poke_verbs
- * * \e array associative array with another array as value
- */
- call_hooks('poke_verbs', $arr);
+ call_hooks('get_emojis', $emojis);
- return $arr;
+ return $emojis;
}
-/**
- * @brief Get an array of mood verbs.
- *
- * @return array
- * * \e index is the verb
- * * \e value is the translated verb
- */
-function get_mood_verbs() {
-
- $arr = [
- 'happy' => t('happy'),
- 'sad' => t('sad'),
- 'mellow' => t('mellow'),
- 'tired' => t('tired'),
- 'perky' => t('perky'),
- 'angry' => t('angry'),
- 'stupefied' => t('stupefied'),
- 'puzzled' => t('puzzled'),
- 'interested' => t('interested'),
- 'bitter' => t('bitter'),
- 'cheerful' => t('cheerful'),
- 'alive' => t('alive'),
- 'annoyed' => t('annoyed'),
- 'anxious' => t('anxious'),
- 'cranky' => t('cranky'),
- 'disturbed' => t('disturbed'),
- 'frustrated' => t('frustrated'),
- 'depressed' => t('depressed'),
- 'motivated' => t('motivated'),
- 'relaxed' => t('relaxed'),
- 'surprised' => t('surprised'),
- ];
-
- /**
- * @hooks mood_verbs
- * * \e array associative array with mood verbs
- */
- call_hooks('mood_verbs', $arr);
-
- return $arr;
+function is_solo_string(string $emoji, string $body) : bool {
+ return empty(trim(str_replace($emoji, '', $body, $count))) && $count === 1;
}
/**
@@ -1371,38 +1342,37 @@ function list_smilies($default_only = false) {
);
$icons = array(
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-heart.gif" alt="&lt;3" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-brokenheart.gif" alt="&lt;/3" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-smile.gif" alt=":-)" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-wink.gif" alt=";-)" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-frown.gif" alt=":-(" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-tongue-out.gif" alt=":-P" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-tongue-out.gif" alt=":-p" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-\"" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-\"" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-x" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-X" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-laughing.gif" alt=":-D" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt="8-|" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt="8-O" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt=":-O" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-thumbsup.gif" alt="\\o/" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="o.O" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="O.o" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="o_O" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="O_o" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-cry.gif" alt=":\'(" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-foot-in-mouth.gif" alt=":-!" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-undecided.gif" alt=":-/" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-embarassed.gif" alt=":-[" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-cool.gif" alt="8-)" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/beer_mug.gif" alt=":beer" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/beer_mug.gif" alt=":homebrew" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/coffee.gif" alt=":coffee" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-facepalm.gif" alt=":facepalm" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/like.gif" alt=":like" />',
- '<img class="smiley" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />'
-
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-heart.gif" alt="&lt;3" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-brokenheart.gif" alt="&lt;/3" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-smile.gif" alt=":-)" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-wink.gif" alt=";-)" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-frown.gif" alt=":-(" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-tongue-out.gif" alt=":-P" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-tongue-out.gif" alt=":-p" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-\"" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-\"" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-x" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-kiss.gif" alt=":-X" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-laughing.gif" alt=":-D" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt="8-|" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt="8-O" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-surprised.gif" alt=":-O" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-thumbsup.gif" alt="\\o/" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="o.O" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="O.o" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="o_O" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-Oo.gif" alt="O_o" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-cry.gif" alt=":\'(" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-foot-in-mouth.gif" alt=":-!" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-undecided.gif" alt=":-/" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-embarassed.gif" alt=":-[" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-cool.gif" alt="8-)" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/beer_mug.gif" alt=":beer" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/beer_mug.gif" alt=":homebrew" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/coffee.gif" alt=":coffee" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/smiley-facepalm.gif" alt=":facepalm" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/like.gif" alt=":like" />',
+ '<img class="smiley emoji" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />'
);
$params = array('texts' => $texts, 'icons' => $icons);
@@ -1441,10 +1411,34 @@ function smilies($s, $sample = false) {
|| (local_channel() && intval(get_pconfig(local_channel(), 'system', 'no_smilies'))))
return $s;
+
$s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism', 'smile_shield', $s);
$s = preg_replace_callback('/<[a-z]+ .*?>/ism', 'smile_shield', $s);
+ if (preg_match_all('/(\:(\w|\+|\-)+\:)(?=|[\!\.\?]|$)/', $s, $match)) {
+ // emoji shortcodes
+ $emojis = get_emojis();
+ foreach ($match[0] as $mtch) {
+ $name = trim($mtch, ':');
+
+ if (!isset($emojis[$name])) {
+ continue;
+ }
+
+ $emoji = $emojis[$name];
+
+ $class = 'emoji';
+ if (is_solo_string($mtch, $s)) {
+ $class .= ' single-emoji';
+ }
+ $img = '<img class="' . $class . '" src="' . $emoji['filepath'] . '" alt="' . trim($emoji['shortname'], ':') . '" title="' . trim($emoji['shortname'], ':') . '" />';
+
+ string_replace($emoji['shortname'], $img, $s);
+ }
+ }
+
+/*
$params = list_smilies();
$params['string'] = $s;
@@ -1455,9 +1449,9 @@ function smilies($s, $sample = false) {
}
} else {
$params['string'] = preg_replace_callback('/&lt;(3+)/','preg_heart',$params['string']);
- $s = str_replace($params['texts'],$params['icons'],$params['string']);
+ $s = str_replace($params['texts'], $params['icons'], $params['string']);
}
-
+*/
$s = preg_replace_callback('/<!--base64:(.*?)-->/ism', 'smile_unshield', $s);
@@ -1595,15 +1589,16 @@ function theme_attachments(&$item) {
$url = z_root() . '/magic?f=&owa=1&hash=' . $item['author_xchan'] . '&bdest=' . bin2hex($r['href'] . '/' . $revision);
}
- //$s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>';
- if (isset($label) && isset($url) && isset($icon) && isset($title))
- $attaches[] = array('label' => $label, 'url' => $url, 'icon' => $icon, 'title' => $title);
+ if (isset($label) && isset($url) && isset($icon) && isset($title)) {
+ array_unshift($attaches, ['label' => $label, 'url' => $url, 'icon' => $icon, 'title' => $title]);
+ }
}
- if (count($attaches) > 0)
+ if ($attaches) {
$s = replace_macros(get_markup_template('item_attach.tpl'), [
'$attaches' => $attaches
]);
+ }
}
return $s;
@@ -1759,7 +1754,7 @@ function prepare_body(&$item,$attach = false,$opts = false) {
$s = '';
$photo = '';
- $is_photo = ((($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) ? true : false);
+ $is_photo = (((in_array($item['verb'], ['Create', ACTIVITY_POST])) && (in_array($item['obj_type'], ['Image', ACTIVITY_OBJ_PHOTO]))) ? true : false);
if ($is_photo) {
$object = json_decode($item['obj'],true);
@@ -1804,7 +1799,7 @@ function prepare_body(&$item,$attach = false,$opts = false) {
}
- $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE ])) ? format_poll($item, $s, $opts) : false);
+ $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],['Create', 'Update', ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE])) ? format_poll($item, $s, $opts) : false);
if ($poll) {
$s = $poll;
}
@@ -2103,7 +2098,7 @@ function prepare_text($text, $content_type = 'text/bbcode', $opts = false) {
function create_export_photo_body(&$item) {
- if(($item['verb'] === ACTIVITY_POST) && ($item['obj_type'] === ACTIVITY_OBJ_PHOTO)) {
+ if((in_array($item['verb'], ['Create', ACTIVITY_POST])) && (in_array($item['obj_type'], ['Image', ACTIVITY_OBJ_PHOTO]))) {
$j = json_decode($item['obj'],true);
if($j) {
$item['body'] .= "\n\n" . (($j['body']) ? $j['body'] : $j['bbcode']);
@@ -2616,7 +2611,7 @@ function trim_and_unpunify($s) {
* @param number $effective_uid
*/
function xchan_query(&$items, $abook = true, $effective_uid = 0) {
- $arr = array();
+ $arr = [];
if($items && count($items)) {
if($effective_uid) {
@@ -2631,6 +2626,8 @@ function xchan_query(&$items, $abook = true, $effective_uid = 0) {
$arr[] = "'" . dbesc($item['owner_xchan']) . "'";
if($item['author_xchan'] && (! in_array("'" . dbesc($item['author_xchan']) . "'",$arr)))
$arr[] = "'" . dbesc($item['author_xchan']) . "'";
+ if($item['source_xchan'] && (! in_array("'" . dbesc($item['source_xchan']) . "'",$arr)))
+ $arr[] = "'" . dbesc($item['source_xchan']) . "'";
}
}
if(count($arr)) {
@@ -2654,6 +2651,7 @@ function xchan_query(&$items, $abook = true, $effective_uid = 0) {
for($x = 0; $x < count($items); $x ++) {
$items[$x]['owner'] = find_xchan_in_array($items[$x]['owner_xchan'],$chans);
$items[$x]['author'] = find_xchan_in_array($items[$x]['author_xchan'],$chans);
+ $items[$x]['source'] = find_xchan_in_array($items[$x]['source_xchan'],$chans);
}
}
}
@@ -2888,6 +2886,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
$replaced = false;
$r = null;
$match = array();
+ $newtag = '';
$termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN);
$termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype);
@@ -2937,10 +2936,11 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
}
// is the link already in str_tags?
- if(! stristr($str_tags,$newtag)) {
+ if (!stristr($str_tags, $newtag)) {
// append or set str_tags
- if(strlen($str_tags))
+ if (strlen($str_tags)) {
$str_tags .= ',';
+ }
$str_tags .= $newtag;
}
diff --git a/include/xchan.php b/include/xchan.php
index 4a2d389c0..b8677c8c4 100644
--- a/include/xchan.php
+++ b/include/xchan.php
@@ -17,6 +17,7 @@ function xchan_store_lowlevel($arr) {
'xchan_guid' => ((array_key_exists('xchan_guid',$arr)) ? $arr['xchan_guid'] : ''),
'xchan_guid_sig' => ((array_key_exists('xchan_guid_sig',$arr)) ? $arr['xchan_guid_sig'] : ''),
'xchan_pubkey' => ((array_key_exists('xchan_pubkey',$arr)) ? $arr['xchan_pubkey'] : ''),
+ 'xchan_epubkey' => ((array_key_exists('xchan_epubkey',$arr)) ? $arr['xchan_epubkey'] : ''),
'xchan_photo_mimetype' => ((array_key_exists('xchan_photo_mimetype',$arr)) ? $arr['xchan_photo_mimetype'] : ''),
'xchan_photo_l' => ((array_key_exists('xchan_photo_l',$arr)) ? $arr['xchan_photo_l'] : ''),
'xchan_photo_m' => ((array_key_exists('xchan_photo_m',$arr)) ? $arr['xchan_photo_m'] : ''),
@@ -32,6 +33,7 @@ function xchan_store_lowlevel($arr) {
'xchan_flags' => ((array_key_exists('xchan_flags',$arr)) ? intval($arr['xchan_flags']) : 0),
'xchan_photo_date' => ((array_key_exists('xchan_photo_date',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_photo_date']) : NULL_DATE),
'xchan_name_date' => ((array_key_exists('xchan_name_date',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_name_date']) : NULL_DATE),
+ 'xchan_updated' => ((array_key_exists('xchan_updated',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_updated']) : NULL_DATE),
'xchan_hidden' => ((array_key_exists('xchan_hidden',$arr)) ? intval($arr['xchan_hidden']) : 0),
'xchan_orphan' => ((array_key_exists('xchan_orphan',$arr)) ? intval($arr['xchan_orphan']) : 0),
'xchan_censored' => ((array_key_exists('xchan_censored',$arr)) ? intval($arr['xchan_censored']) : 0),