From 8bb33dccd1d945c849c7006ee56a73fc9404323c Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 15 Jul 2023 20:12:08 +0000 Subject: [PATCH] Unified BBCode conversion, improved proxy functionality --- src/Content/OEmbed.php | 3 +-- src/Content/Text/BBCode.php | 8 ++++---- src/Content/Text/NPF.php | 2 +- src/Core/System.php | 10 ++++++---- src/Factory/Api/Mastodon/Field.php | 2 +- src/Model/Event.php | 9 +++++---- src/Model/User.php | 11 +++++++++++ src/Module/Api/Friendica/Profile/Show.php | 2 +- src/Module/Debug/Babel.php | 6 +++--- src/Module/Moderation/Report/Create.php | 2 +- src/Module/Notifications/Introductions.php | 2 +- src/Module/Register.php | 2 +- src/Module/Tos.php | 5 +++-- src/Navigation/Notifications/Entity/Notify.php | 4 ++-- src/Navigation/Notifications/Factory/Introduction.php | 4 ++-- src/Object/Api/Friendica/Notification.php | 2 +- src/Object/Api/Mastodon/ScheduledStatus.php | 2 +- src/Profile/ProfileField/Entity/ProfileField.php | 6 +++++- src/Profile/ProfileField/Factory/ProfileField.php | 6 +++++- src/Util/EMailer/NotifyMailBuilder.php | 2 +- src/Util/EMailer/SystemMailBuilder.php | 2 +- static/settings.config.php | 4 ++++ 22 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/Content/OEmbed.php b/src/Content/OEmbed.php index 7afdfac35c..df2cafea45 100644 --- a/src/Content/OEmbed.php +++ b/src/Content/OEmbed.php @@ -312,8 +312,7 @@ class OEmbed */ public static function BBCode2HTML(string $text): string { - $stopoembed = DI::config()->get('system', 'no_oembed'); - if ($stopoembed == true) { + if (DI::config()->get('system', 'no_oembed')) { return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "" . DI::l10n()->t('Embedding disabled') . " : $1", $text); } return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", [self::class, 'replaceCallback'], $text); diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 3635ba874c..503adbd57c 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -142,7 +142,7 @@ class BBCode break; case 'title': - $value = self::convert(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), false, true); + $value = self::convertForUriId(0, html_entity_decode($value, ENT_QUOTES, 'UTF-8'), BBCode::EXTERNAL); $value = html_entity_decode($value, ENT_QUOTES, 'UTF-8'); $value = str_replace(['[', ']'], ['[', ']'], $value); $data['title'] = $value; @@ -236,7 +236,7 @@ class BBCode // Remove attachment $text = self::replaceAttachment($text); - $naked_text = HTML::toPlaintext(self::convert($text, false, 0, true), 0, !$keep_urls); + $naked_text = HTML::toPlaintext(self::convert($text, false, BBCode::EXTERNAL, true), 0, !$keep_urls); DI::profiler()->stopRecording(); return $naked_text; @@ -2065,7 +2065,7 @@ class BBCode // Convert it to HTML - don't try oembed if ($for_diaspora) { - $text = self::convert($text, false, self::DIASPORA); + $text = self::convertForUriId(0, $text, self::DIASPORA); // Add all tags that maybe were removed if (preg_match_all("/#\[url\=([$url_search_string]*)\](.*?)\[\/url\]/ism", $original_text, $tags)) { @@ -2079,7 +2079,7 @@ class BBCode $text = $text . ' ' . $tagline; } } else { - $text = self::convert($text, false, self::CONNECTORS); + $text = self::convertForUriId(0, $text, self::CONNECTORS); } // If a link is followed by a quote then there should be a newline before it diff --git a/src/Content/Text/NPF.php b/src/Content/Text/NPF.php index 2f0b360837..f5a6e2dc18 100644 --- a/src/Content/Text/NPF.php +++ b/src/Content/Text/NPF.php @@ -45,7 +45,7 @@ class NPF { $bbcode = self::prepareBody($bbcode); - $html = BBCode::convert($bbcode, false, BBCode::NPF); + $html = BBCode::convertForUriId($uri_id, $bbcode, BBCode::NPF); if (empty($html)) { return []; } diff --git a/src/Core/System.php b/src/Core/System.php index 00bdcd455c..602d85c83c 100644 --- a/src/Core/System.php +++ b/src/Core/System.php @@ -25,6 +25,7 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\DI; +use Friendica\Model\User; use Friendica\Module\Response; use Friendica\Network\HTTPException\FoundException; use Friendica\Network\HTTPException\MovedPermanentlyException; @@ -226,9 +227,10 @@ class System * @param integer $depth How many calls to include in the stacks after filtering * @param int $offset How many calls to shave off the top of the stack, for example if * this is called from a centralized method that isn't relevant to the callstack + * @param bool $full If enabled, the callstack is not compacted * @return string */ - public static function callstack(int $depth = 4, int $offset = 0): string + public static function callstack(int $depth = 4, int $offset = 0, bool $full = false): string { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); @@ -243,7 +245,7 @@ class System while ($func = array_pop($trace)) { if (!empty($func['class'])) { - if (in_array($previous['function'], ['insert', 'fetch', 'toArray', 'exists', 'count', 'selectFirst', 'selectToArray', + if (!$full && in_array($previous['function'], ['insert', 'fetch', 'toArray', 'exists', 'count', 'selectFirst', 'selectToArray', 'select', 'update', 'delete', 'selectFirstForUser', 'selectForUser']) && (substr($previous['class'], 0, 15) === 'Friendica\Model')) { continue; @@ -251,7 +253,7 @@ class System // Don't show multiple calls from the Database classes to show the essential parts of the callstack $func['database'] = in_array($func['class'], ['Friendica\Database\DBA', 'Friendica\Database\Database']); - if (!$previous['database'] || !$func['database']) { + if ($full || !$previous['database'] || !$func['database']) { $classparts = explode("\\", $func['class']); $callstack[] = array_pop($classparts).'::'.$func['function'] . (isset($func['line']) ? ' (' . $func['line'] . ')' : ''); $previous = $func; @@ -669,7 +671,7 @@ class System if (DI::config()->get('system', 'tosdisplay')) { $rulelist = DI::config()->get('system', 'tosrules') ?: DI::config()->get('system', 'tostext'); - $html = BBCode::convert($rulelist, false, BBCode::EXTERNAL); + $html = BBCode::convertForUriId(User::getSystemUriId(), $rulelist, BBCode::EXTERNAL); $msg = HTML::toPlaintext($html, 0, true); foreach (explode("\n", trim($msg)) as $line) { diff --git a/src/Factory/Api/Mastodon/Field.php b/src/Factory/Api/Mastodon/Field.php index 8b24eb4861..e4fe203057 100644 --- a/src/Factory/Api/Mastodon/Field.php +++ b/src/Factory/Api/Mastodon/Field.php @@ -38,7 +38,7 @@ class Field extends BaseFactory */ public function createFromProfileField(ProfileField $profileField): \Friendica\Object\Api\Mastodon\Field { - return new \Friendica\Object\Api\Mastodon\Field($profileField->label, BBCode::convert($profileField->value, false, BBCode::ACTIVITYPUB)); + return new \Friendica\Object\Api\Mastodon\Field($profileField->label, BBCode::convertForUriId($profileField->uriId, $profileField->value, BBCode::ACTIVITYPUB)); } /** diff --git a/src/Model/Event.php b/src/Model/Event.php index bc03370647..6ac1e2774e 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -928,7 +928,7 @@ class Event } // Format the event location. - $location = self::locationToArray($item['event-location']); + $location = self::locationToArray($item['event-location'], $item['uri-id']); // Construct the profile link (magic-auth). $author = [ @@ -978,7 +978,8 @@ class Event * Note: The string must only contain location data. A string with no bbcode will be * handled as location name. * - * @param string $s The string with the bbcode formatted location data. + * @param string $s The string with the bbcode formatted location data. + * @param int $uri_id The uri-id of the related post * * @return array The array with the location data. * 'name' => The name of the location,
@@ -986,7 +987,7 @@ class Event * 'coordinates' => Latitude and longitude (e.g. '48.864716,2.349014').
* @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function locationToArray(string $s = ''): array + private static function locationToArray(string $s, int $uri_id): array { if ($s == '') { return []; @@ -1012,7 +1013,7 @@ class Event } } - $location['name'] = BBCode::convert($location['name']); + $location['name'] = BBCode::convertForUriId($uri_id, $location['name']); // Construct the map HTML. if (isset($location['address'])) { diff --git a/src/Model/User.php b/src/Model/User.php index 854961154b..89d75849fe 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -132,6 +132,17 @@ class User return null; } + /** + * Get the Uri-Id of the system account + * + * @return integer + */ + public static function getSystemUriId(): int + { + $system = self::getSystemAccount(); + return $system['uri-id'] ?? 0; + } + /** * Fetch the system account * diff --git a/src/Module/Api/Friendica/Profile/Show.php b/src/Module/Api/Friendica/Profile/Show.php index 28909f0e39..b97fcdcab9 100644 --- a/src/Module/Api/Friendica/Profile/Show.php +++ b/src/Module/Api/Friendica/Profile/Show.php @@ -78,7 +78,7 @@ class Show extends BaseApi foreach ($profileFields as $profileField) { $custom_fields[] = [ 'label' => $profileField->label, - 'value' => BBCode::convert($profileField->value, false, BBCode::TWITTER_API), + 'value' => BBCode::convertForUriId($profileField->uriId, $profileField->value, BBCode::TWITTER_API), ]; } diff --git a/src/Module/Debug/Babel.php b/src/Module/Debug/Babel.php index 560d002a1b..a914f4fe90 100644 --- a/src/Module/Debug/Babel.php +++ b/src/Module/Debug/Babel.php @@ -58,7 +58,7 @@ class Babel extends BaseModule 'content' => visible_whitespace($plain) ]; - $html = Text\BBCode::convert($bbcode); + $html = Text\BBCode::convertForUriId(0, $bbcode); $results[] = [ 'title' => DI::l10n()->t('BBCode::convert (raw HTML)'), 'content' => visible_whitespace($html) @@ -125,7 +125,7 @@ class Babel extends BaseModule 'title' => DI::l10n()->t('PageInfo::appendToBody'), 'content' => visible_whitespace($body2) ]; - $html3 = Text\BBCode::convert($body2); + $html3 = Text\BBCode::convertForUriId(0, $body2); $results[] = [ 'title' => DI::l10n()->t('PageInfo::appendToBody => BBCode::convert (raw HTML)'), 'content' => visible_whitespace($html3) @@ -203,7 +203,7 @@ class Babel extends BaseModule 'content' => visible_whitespace($bbcode) ]; - $html2 = Text\BBCode::convert($bbcode); + $html2 = Text\BBCode::convertForUriId(0, $bbcode); $results[] = [ 'title' => DI::l10n()->t('HTML::toBBCode => BBCode::convert'), 'content' => $html2 diff --git a/src/Module/Moderation/Report/Create.php b/src/Module/Moderation/Report/Create.php index 0e0e4c925e..1185730aba 100644 --- a/src/Module/Moderation/Report/Create.php +++ b/src/Module/Moderation/Report/Create.php @@ -337,7 +337,7 @@ class Create extends BaseModule '$contact' => $contact, '$category' => $category, '$rules' => $rules ?? [], - '$comment' => BBCode::convert($this->session->get('report_comment') ?? '', false, ), + '$comment' => BBCode::convertForUriId($contact['uri-id'] ?? 0, $this->session->get('report_comment') ?? '', BBCode::EXTERNAL), '$posts' => count($request['uri-ids']), ]); } diff --git a/src/Module/Notifications/Introductions.php b/src/Module/Notifications/Introductions.php index 246bed5402..1c4a98b47b 100644 --- a/src/Module/Notifications/Introductions.php +++ b/src/Module/Notifications/Introductions.php @@ -147,7 +147,7 @@ class Introductions extends BaseNotifications $knowyou = ''; } - $convertedName = BBCode::convert($Introduction->getName()); + $convertedName = BBCode::convertForUriId($owner['uri-id'], $Introduction->getName()); $helptext = $this->t('Shall your connection be bidirectional or not?'); $helptext2 = $this->t('Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed.', $convertedName, $convertedName); diff --git a/src/Module/Register.php b/src/Module/Register.php index d26fb0a3d3..a62525a986 100644 --- a/src/Module/Register.php +++ b/src/Module/Register.php @@ -150,7 +150,7 @@ class Register extends BaseModule '$invite_label' => DI::l10n()->t('Your invitation code: '), '$invite_id' => $invite_id, '$regtitle' => DI::l10n()->t('Registration'), - '$registertext' => BBCode::convert(DI::config()->get('config', 'register_text', '')), + '$registertext' => BBCode::convertForUriId(User::getSystemUriId(), DI::config()->get('config', 'register_text', '')), '$fillwith' => $fillwith, '$fillext' => $fillext, '$oidlabel' => $oidlabel, diff --git a/src/Module/Tos.php b/src/Module/Tos.php index af64810086..3b151c31f5 100644 --- a/src/Module/Tos.php +++ b/src/Module/Tos.php @@ -27,6 +27,7 @@ use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\L10n; use Friendica\Core\Renderer; use Friendica\Content\Text\BBCode; +use Friendica\Model\User; use Friendica\Util\Profiler; use Psr\Log\LoggerInterface; @@ -98,9 +99,9 @@ class Tos extends BaseModule return Renderer::replaceMacros($tpl, [ '$title' => $this->t('Terms of Service'), - '$tostext' => BBCode::convert($this->config->get('system', 'tostext')), + '$tostext' => BBCode::convertForUriId(User::getSystemUriId(), $this->config->get('system', 'tostext')), '$rulestitle' => $this->t('Rules'), - '$rules' => BBCode::convert($rules), + '$rules' => BBCode::convertForUriId(User::getSystemUriId(), $rules), '$displayprivstatement' => $this->config->get('system', 'tosprivstatement'), '$privstatementtitle' => $this->t('Privacy Statement'), '$privacy_operate' => $this->t('At the time of registration, and for providing communications between the user account and their contacts, the user has to provide a display name (pen name), an username (nickname) and a working email address. The names will be accessible on the profile page of the account by any visitor of the page, even if other profile details are not displayed. The email address will only be used to send the user notifications about interactions, but wont be visibly displayed. The listing of an account in the node\'s user directory or the global user directory is optional and can be controlled in the user settings, it is not necessary for communication.'), diff --git a/src/Navigation/Notifications/Entity/Notify.php b/src/Navigation/Notifications/Entity/Notify.php index 45f450b1d1..56db3dc5c8 100644 --- a/src/Navigation/Notifications/Entity/Notify.php +++ b/src/Navigation/Notifications/Entity/Notify.php @@ -118,7 +118,7 @@ class Notify extends BaseEntity public function updateMsgFromPreamble($epreamble) { $this->msg = Renderer::replaceMacros($epreamble, ['$itemlink' => $this->link->__toString()]); - $this->msg_cache = self::formatMessage($this->name_cache, strip_tags(BBCode::convert($this->msg))); + $this->msg_cache = self::formatMessage($this->name_cache, strip_tags(BBCode::convertForUriId(0, $this->msg, BBCode::EXTERNAL))); } /** @@ -134,6 +134,6 @@ class Notify extends BaseEntity */ public static function formatMessage(string $name, string $message): string { - return str_replace('{0}', '' . strip_tags(BBCode::convert($name)) . '', htmlspecialchars($message)); + return str_replace('{0}', '' . strip_tags(BBCode::convertForUriId(0, $name, BBCode::EXTERNAL)) . '', htmlspecialchars($message)); } } diff --git a/src/Navigation/Notifications/Factory/Introduction.php b/src/Navigation/Notifications/Factory/Introduction.php index 3d176743c0..5078cac3ca 100644 --- a/src/Navigation/Notifications/Factory/Introduction.php +++ b/src/Navigation/Notifications/Factory/Introduction.php @@ -163,8 +163,8 @@ class Introduction extends BaseFactory 'contact_id' => $intro['contact-id'], 'photo' => Contact::getPhoto($intro), 'name' => $intro['name'], - 'location' => BBCode::convert($intro['location'], false), - 'about' => BBCode::convert($intro['about'], false), + 'location' => BBCode::convertForUriId($intro['uri-id'], $intro['location'], BBCode::EXTERNAL), + 'about' => BBCode::convertForUriId ($intro['uri-id'], $intro['about'], BBCode::EXTERNAL), 'keywords' => $intro['keywords'], 'hidden' => $intro['hidden'] == 1, 'post_newfriend' => (intval($this->pConfig->get($this->session->getLocalUserId(), 'system', 'post_newfriend')) ? '1' : 0), diff --git a/src/Object/Api/Friendica/Notification.php b/src/Object/Api/Friendica/Notification.php index 92e6ff0445..df59bb6b8c 100644 --- a/src/Object/Api/Friendica/Notification.php +++ b/src/Object/Api/Friendica/Notification.php @@ -98,7 +98,7 @@ class Notification extends BaseDataTransferObject $this->date_rel = Temporal::getRelativeDate($this->date); try { - $this->msg_html = BBCode::convert($this->msg, false); + $this->msg_html = BBCode::convertForUriId($Notify->uriId, $this->msg, BBCode::EXTERNAL); } catch (\Exception $e) { $this->msg_html = ''; } diff --git a/src/Object/Api/Mastodon/ScheduledStatus.php b/src/Object/Api/Mastodon/ScheduledStatus.php index de28b048a1..65506a21d5 100644 --- a/src/Object/Api/Mastodon/ScheduledStatus.php +++ b/src/Object/Api/Mastodon/ScheduledStatus.php @@ -67,7 +67,7 @@ class ScheduledStatus extends BaseDataTransferObject $this->scheduled_at = DateTimeFormat::utc($delayed_post['delayed'], DateTimeFormat::JSON); $this->params = [ - 'text' => BBCode::convert(BBCode::setMentionsToNicknames($parameters['item']['body'] ?? ''), false, BBCode::MASTODON_API), + 'text' => BBCode::convertForUriId($parameters['item']['uri-id'] ?? 0, BBCode::setMentionsToNicknames($parameters['item']['body'] ?? ''), BBCode::MASTODON_API), 'media_ids' => $media_ids, 'sensitive' => null, 'spoiler_text' => $parameters['item']['title'] ?? '', diff --git a/src/Profile/ProfileField/Entity/ProfileField.php b/src/Profile/ProfileField/Entity/ProfileField.php index a2a7c43ce0..2461e02bd7 100644 --- a/src/Profile/ProfileField/Entity/ProfileField.php +++ b/src/Profile/ProfileField/Entity/ProfileField.php @@ -34,6 +34,7 @@ use Friendica\Security\PermissionSet\Entity\PermissionSet; * * @property-read int|null $id * @property-read int $uid + * @property-read int $uriId * @property-read int $order * @property-read string $label * @property-read string $value @@ -50,6 +51,8 @@ class ProfileField extends BaseEntity /** @var int */ protected $uid; /** @var int */ + protected $uriId; + /** @var int */ protected $order; /** @var string */ protected $label; @@ -60,7 +63,7 @@ class ProfileField extends BaseEntity /** @var \DateTime */ protected $edited; - public function __construct(int $uid, int $order, string $label, string $value, \DateTime $created, \DateTime $edited, PermissionSet $permissionSet, int $id = null) + public function __construct(int $uid, int $order, string $label, string $value, \DateTime $created, \DateTime $edited, PermissionSet $permissionSet, int $id = null, int $uriId = null) { $this->permissionSet = $permissionSet; $this->uid = $uid; @@ -70,6 +73,7 @@ class ProfileField extends BaseEntity $this->created = $created; $this->edited = $edited; $this->id = $id; + $this->uriId = $uriId; } /** diff --git a/src/Profile/ProfileField/Factory/ProfileField.php b/src/Profile/ProfileField/Factory/ProfileField.php index cad542bc7d..3c8e4673ea 100644 --- a/src/Profile/ProfileField/Factory/ProfileField.php +++ b/src/Profile/ProfileField/Factory/ProfileField.php @@ -26,6 +26,7 @@ use Friendica\Profile\ProfileField\Exception\UnexpectedPermissionSetException; use Friendica\Security\PermissionSet\Factory\PermissionSet as PermissionSetFactory; use Friendica\Profile\ProfileField\Entity; use Friendica\Capabilities\ICanCreateFromTableRow; +use Friendica\Model\User; use Friendica\Security\PermissionSet\Entity\PermissionSet; use Psr\Log\LoggerInterface; @@ -54,6 +55,8 @@ class ProfileField extends BaseFactory implements ICanCreateFromTableRow throw new UnexpectedPermissionSetException('Either set the PermissionSet fields (join) or the PermissionSet itself'); } + $owner = User::getOwnerDataById($row['uid']); + return new Entity\ProfileField( $row['uid'], $row['order'], @@ -69,7 +72,8 @@ class ProfileField extends BaseFactory implements ICanCreateFromTableRow $row['deny_gid'], $row['psid'] ), - $row['id'] ?? null + $row['id'] ?? null, + $owner['uri-id'] ?? null ); } diff --git a/src/Util/EMailer/NotifyMailBuilder.php b/src/Util/EMailer/NotifyMailBuilder.php index b7e9c51d42..4191dbba24 100644 --- a/src/Util/EMailer/NotifyMailBuilder.php +++ b/src/Util/EMailer/NotifyMailBuilder.php @@ -179,7 +179,7 @@ class NotifyMailBuilder extends MailBuilder */ protected function getHtmlMessage() { - $htmlVersion = BBCode::convert($this->body); + $htmlVersion = BBCode::convertForUriId(0, $this->body, BBCode::EXTERNAL); // load the template for private message notifications $tpl = Renderer::getMarkupTemplate('email/notify/html.tpl'); diff --git a/src/Util/EMailer/SystemMailBuilder.php b/src/Util/EMailer/SystemMailBuilder.php index 3c50ba9165..68e19ae83d 100644 --- a/src/Util/EMailer/SystemMailBuilder.php +++ b/src/Util/EMailer/SystemMailBuilder.php @@ -100,7 +100,7 @@ class SystemMailBuilder extends MailBuilder '$preamble' => str_replace("\n", "
\n", $this->preamble), '$thanks' => $this->l10n->t('thanks'), '$site_admin' => $this->siteAdmin, - '$htmlversion' => BBCode::convert($this->body), + '$htmlversion' => BBCode::convertForUriId(0, $this->body, BBCode::EXTERNAL), ]); } diff --git a/static/settings.config.php b/static/settings.config.php index 47d1a51500..335b702561 100644 --- a/static/settings.config.php +++ b/static/settings.config.php @@ -164,6 +164,10 @@ return [ // Allow pseudonyms (true) or enforce a space between first name and last name in Full name, as an anti spam measure (false). 'no_regfullname' => true, + // no_oembed_rich_content (Boolean) + // If enabled, allow OEmbed for all URLs. Disabled by default. + 'no_oembed_rich_content' => true, + // optimize_tables (Boolean) // Periodically (once an hour) run an "optimize table" command for cache tables 'optimize_tables' => false,