diff --git a/include/api.php b/include/api.php index 246a716fac..0f7fa85bdd 100644 --- a/include/api.php +++ b/include/api.php @@ -1046,7 +1046,7 @@ function api_statuses_mediap($type) //$txt = urldecode(requestdata('status')); if ((strpos($txt, '<') !== false) || (strpos($txt, '>') !== false)) { - $txt = html2bb_video($txt); + $txt = HTML::toBBCodeVideo($txt); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); @@ -1092,7 +1092,7 @@ function api_statuses_update($type) if (requestdata('htmlstatus')) { $txt = requestdata('htmlstatus'); if ((strpos($txt, '<') !== false) || (strpos($txt, '>') !== false)) { - $txt = html2bb_video($txt); + $txt = HTML::toBBCodeVideo($txt); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); diff --git a/include/text.php b/include/text.php index 5da54b5fc9..cfa6c06753 100644 --- a/include/text.php +++ b/include/text.php @@ -27,6 +27,7 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Model\FileTag; use Friendica\Util\XML; +use Friendica\Content\Text\HTML; require_once "include/conversation.php"; @@ -163,19 +164,6 @@ function autoname($len) { return $word; } -/** - * Loader for infinite scrolling - * @return string html for loader - */ -function scroll_loader() { - $tpl = Renderer::getMarkupTemplate("scroll_loader.tpl"); - return Renderer::replaceMacros($tpl, [ - 'wait' => L10n::t('Loading more entries...'), - 'end' => L10n::t('The end') - ]); -} - - /** * Turn user/group ACLs stored as angle bracketed text into arrays * @@ -349,188 +337,6 @@ function qp($s) { return str_replace("%", "=", rawurlencode($s)); } - -/** - * Get html for contact block. - * - * @template contact_block.tpl - * @hook contact_block_end (contacts=>array, output=>string) - * @return string - */ -function contact_block() { - $o = ''; - $a = get_app(); - - $shown = PConfig::get($a->profile['uid'], 'system', 'display_friend_count', 24); - if ($shown == 0) { - return; - } - - if (!is_array($a->profile) || $a->profile['hide-friends']) { - return $o; - } - $r = q("SELECT COUNT(*) AS `total` FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `blocked` - AND NOT `pending` AND NOT `hidden` AND NOT `archive` - AND `network` IN ('%s', '%s', '%s')", - intval($a->profile['uid']), - DBA::escape(Protocol::DFRN), - DBA::escape(Protocol::OSTATUS), - DBA::escape(Protocol::DIASPORA) - ); - if (DBA::isResult($r)) { - $total = intval($r[0]['total']); - } - if (!$total) { - $contacts = L10n::t('No contacts'); - $micropro = null; - } else { - // Splitting the query in two parts makes it much faster - $r = q("SELECT `id` FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `blocked` - AND NOT `pending` AND NOT `hidden` AND NOT `archive` - AND `network` IN ('%s', '%s', '%s') - ORDER BY RAND() LIMIT %d", - intval($a->profile['uid']), - DBA::escape(Protocol::DFRN), - DBA::escape(Protocol::OSTATUS), - DBA::escape(Protocol::DIASPORA), - intval($shown) - ); - if (DBA::isResult($r)) { - $contacts = []; - foreach ($r AS $contact) { - $contacts[] = $contact["id"]; - } - $r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `thumb`, `network` FROM `contact` WHERE `id` IN (%s)", - DBA::escape(implode(",", $contacts))); - - if (DBA::isResult($r)) { - $contacts = L10n::tt('%d Contact', '%d Contacts', $total); - $micropro = []; - foreach ($r as $rr) { - $micropro[] = micropro($rr, true, 'mpfriend'); - } - } - } - } - - $tpl = Renderer::getMarkupTemplate('contact_block.tpl'); - $o = Renderer::replaceMacros($tpl, [ - '$contacts' => $contacts, - '$nickname' => $a->profile['nickname'], - '$viewcontacts' => L10n::t('View Contacts'), - '$micropro' => $micropro, - ]); - - $arr = ['contacts' => $r, 'output' => $o]; - - Addon::callHooks('contact_block_end', $arr); - return $o; - -} - - -/** - * @brief Format contacts as picture links or as texxt links - * - * @param array $contact Array with contacts which contains an array with - * int 'id' => The ID of the contact - * int 'uid' => The user ID of the user who owns this data - * string 'name' => The name of the contact - * string 'url' => The url to the profile page of the contact - * string 'addr' => The webbie of the contact (e.g.) username@friendica.com - * string 'network' => The network to which the contact belongs to - * string 'thumb' => The contact picture - * string 'click' => js code which is performed when clicking on the contact - * @param boolean $redirect If true try to use the redir url if it's possible - * @param string $class CSS class for the - * @param boolean $textmode If true display the contacts as text links - * if false display the contacts as picture links - - * @return string Formatted html - */ -function micropro($contact, $redirect = false, $class = '', $textmode = false) { - - // Use the contact URL if no address is available - if (!x($contact, "addr")) { - $contact["addr"] = $contact["url"]; - } - - $url = $contact['url']; - $sparkle = ''; - $redir = false; - - if ($redirect) { - $url = Contact::magicLink($contact['url']); - if (strpos($url, 'redir/') === 0) { - $sparkle = ' sparkle'; - } - } - - // If there is some js available we don't need the url - if (x($contact, 'click')) { - $url = ''; - } - - return Renderer::replaceMacros(Renderer::getMarkupTemplate(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'),[ - '$click' => defaults($contact, 'click', ''), - '$class' => $class, - '$url' => $url, - '$photo' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB), - '$name' => $contact['name'], - 'title' => $contact['name'] . ' [' . $contact['addr'] . ']', - '$parkle' => $sparkle, - '$redir' => $redir, - - ]); -} - -/** - * Search box. - * - * @param string $s Search query. - * @param string $id HTML id - * @param string $url Search url. - * @param bool $save Show save search button. - * @param bool $aside Display the search widgit aside. - * - * @return string Formatted HTML. - */ -function search($s, $id = 'search-box', $url = 'search', $save = false, $aside = true) -{ - $mode = 'text'; - - if (strpos($s, '#') === 0) { - $mode = 'tag'; - } - $save_label = $mode === 'text' ? L10n::t('Save') : L10n::t('Follow'); - - $values = [ - '$s' => htmlspecialchars($s), - '$id' => $id, - '$action_url' => $url, - '$search_label' => L10n::t('Search'), - '$save_label' => $save_label, - '$savedsearch' => local_user() && Feature::isEnabled(local_user(),'savedsearch'), - '$search_hint' => L10n::t('@name, !forum, #tags, content'), - '$mode' => $mode - ]; - - if (!$aside) { - $values['$searchoption'] = [ - L10n::t("Full Text"), - L10n::t("Tags"), - L10n::t("Contacts")]; - - if (Config::get('system','poco_local_search')) { - $values['$searchoption'][] = L10n::t("Forums"); - } - } - - return Renderer::replaceMacros(Renderer::getMarkupTemplate('searchbox.tpl'), $values); -} - /** * @brief Check for a valid email string * @@ -542,19 +348,6 @@ function valid_email($email_address) return preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/', $email_address); } - -/** - * Replace naked text hyperlink with HTML formatted hyperlink - * - * @param string $s - */ -function linkify($s) { - $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\'\%\$\!\+]*)/", ' $1', $s); - $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$s); - return $s; -} - - /** * Load poke verbs * @@ -888,7 +681,7 @@ function prepare_body(array &$item, $attach = false, $is_preview = false) $s = preg_replace('|(]+src="[^"]+/photo/[0-9a-f]+)-[0-9]|', "$1-" . $ps, $s); } - $s = apply_content_filter($s, $filter_reasons); + $s = HTML::applyContentFilter($s, $filter_reasons); $hook_data = ['item' => $item, 'html' => $s]; Addon::callHooks('prepare_body_final', $hook_data); @@ -896,30 +689,6 @@ function prepare_body(array &$item, $attach = false, $is_preview = false) return $hook_data['html']; } -/** - * Given a HTML text and a set of filtering reasons, adds a content hiding header with the provided reasons - * - * Reasons are expected to have been translated already. - * - * @param string $html - * @param array $reasons - * @return string - */ -function apply_content_filter($html, array $reasons) -{ - if (count($reasons)) { - $tpl = Renderer::getMarkupTemplate('wall/content_filter.tpl'); - $html = Renderer::replaceMacros($tpl, [ - '$reasons' => $reasons, - '$rnd' => random_string(8), - '$openclose' => L10n::t('Click to open/close'), - '$html' => $html - ]); - } - - return $html; -} - /** * @brief Given a text string, convert from bbcode to html and add smilie icons. * @@ -1049,17 +818,6 @@ function get_plink($item) { return $ret; } - -/** - * replace html amp entity with amp char - * @param string $s - * @return string - */ -function unamp($s) { - return str_replace('&', '&', $s); -} - - /** * return number of bytes in size (K, M, G) * @param string $size_str @@ -1121,16 +879,6 @@ function base64url_decode($s) { } -/** - * return div element with class 'clear' - * @return string - * @deprecated - */ -function cleardiv() { - return '
'; -} - - function bb_translate_video($s) { $matches = null; @@ -1147,59 +895,6 @@ function bb_translate_video($s) { return $s; } -function html2bb_video($s) { - - $s = preg_replace('#]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)#ism', - '[youtube]$2[/youtube]', $s); - - $s = preg_replace('#](.*?)https?://www.youtube.com/embed/([A-Za-z0-9\-_=]+)(.*?)#ism', - '[youtube]$2[/youtube]', $s); - - $s = preg_replace('#](.*?)https?://player.vimeo.com/video/([0-9]+)(.*?)#ism', - '[vimeo]$2[/vimeo]', $s); - - return $s; -} - -/** - * transform link href and img src from relative to absolute - * - * @param string $text - * @param string $base base url - * @return string - */ -function reltoabs($text, $base) { - if (empty($base)) { - return $text; - } - - $base = rtrim($base,'/'); - - $base2 = $base . "/"; - - // Replace links - $pattern = "/]*) href=\"(?!http|https|\/)([^\"]*)\"/"; - $replace = " L10n::t('Saved Searches'), '$add' => L10n::t('add'), - '$searchbox' => search($search, 'netsearch-box', $srchurl, true), + '$searchbox' => HTML::search($search, 'netsearch-box', $srchurl, true), '$saved' => $saved, ]); @@ -348,7 +349,7 @@ function networkConversation(App $a, $items, Pager $pager, $mode, $update, $orde if (!$update) { if (PConfig::get(local_user(), 'system', 'infinite_scroll')) { - $o .= scroll_loader(); + $o .= HTML::scrollLoader(); } else { $o .= $pager->renderMinimal(count($items)); } diff --git a/mod/profperm.php b/mod/profperm.php index ee5e2f23d7..5d7d8ed94b 100644 --- a/mod/profperm.php +++ b/mod/profperm.php @@ -7,6 +7,7 @@ use Friendica\Core\Config; use Friendica\Core\L10n; use Friendica\Core\PConfig; use Friendica\Core\Protocol; +use Friendica\Content\Text\HTML; use Friendica\Database\DBA; use Friendica\Model\Profile; @@ -133,7 +134,7 @@ function profperm_content(App $a) { foreach($members as $member) { if ($member['url']) { $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['id'] . '); return true;'; - $o .= micropro($member,true,'mpprof', $textmode); + $o .= HTML::micropro($member,true,'mpprof', $textmode); } } $o .= '
'; @@ -155,7 +156,7 @@ function profperm_content(App $a) { foreach($r as $member) { if (!in_array($member['id'],$ingroup)) { $member['click'] = 'profChangeMember(' . $profile['id'] . ',' . $member['id'] . '); return true;'; - $o .= micropro($member,true,'mpprof',$textmode); + $o .= HTML::micropro($member,true,'mpprof',$textmode); } } } diff --git a/mod/search.php b/mod/search.php index 37dacadddf..809a6f7e86 100644 --- a/mod/search.php +++ b/mod/search.php @@ -7,6 +7,7 @@ use Friendica\App; use Friendica\Content\Feature; use Friendica\Content\Nav; use Friendica\Content\Pager; +use Friendica\Content\Text\HTML; use Friendica\Core\Cache; use Friendica\Core\Config; use Friendica\Core\L10n; @@ -163,7 +164,7 @@ function search_content(App $a) { 'name' => "search-header", '$title' => L10n::t("Search"), '$title_size' => 3, - '$content' => search($search,'search-box','search',((local_user()) ? true : false), false) + '$content' => HTML::search($search,'search-box','search',((local_user()) ? true : false), false) ]); if (strpos($search,'#') === 0) { diff --git a/src/Content/ForumManager.php b/src/Content/ForumManager.php index a47d70ab38..97917cfd2a 100644 --- a/src/Content/ForumManager.php +++ b/src/Content/ForumManager.php @@ -7,6 +7,7 @@ namespace Friendica\Content; use Friendica\Core\Protocol; use Friendica\Content\Feature; +use Friendica\Content\Text\HTML; use Friendica\Core\L10n; use Friendica\Core\Renderer; use Friendica\Core\System; @@ -169,7 +170,7 @@ class ForumManager $total_shown = 0; $forumlist = ''; foreach ($contacts as $contact) { - $forumlist .= micropro($contact, false, 'forumlist-profile-advanced'); + $forumlist .= HTML::micropro($contact, false, 'forumlist-profile-advanced'); $total_shown ++; if ($total_shown == $show_total) { break; diff --git a/src/Content/Text/HTML.php b/src/Content/Text/HTML.php index c256717a15..6e3bd571b3 100644 --- a/src/Content/Text/HTML.php +++ b/src/Content/Text/HTML.php @@ -1,5 +1,4 @@

", - "

", - ], [ - "
  • ", - "
  • ", - ], $message + "
  • ", + "

  • ", + ], + [ + "
  • ", + "
  • ", + ], + $message ); // remove namespaces @@ -184,8 +193,13 @@ class HTML self::tagToBBCode($doc, 'p', ['class' => 'MsoNormal', 'style' => 'margin-left:35.4pt'], '[quote]', '[/quote]'); // Outlook-Quote - Variant 2 - self::tagToBBCode($doc, 'div', ['style' => 'border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'], - '[quote]', '[/quote]'); + self::tagToBBCode( + $doc, + 'div', + ['style' => 'border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'], + '[quote]', + '[/quote]' + ); // MyBB-Stuff self::tagToBBCode($doc, 'span', ['style' => 'text-decoration: underline;'], '[u]', '[/u]'); @@ -274,8 +288,7 @@ class HTML self::tagToBBCode($doc, 'a', ['href' => '/mailto:(.+)/'], '[mail=$1]', '[/mail]'); self::tagToBBCode($doc, 'a', ['href' => '/(.+)/'], '[url=$1]', '[/url]'); - self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'], '[img=$2x$3]$1', - '[/img]'); + self::tagToBBCode($doc, 'img', ['src' => '/(.+)/', 'width' => '/(\d+)/', 'height' => '/(\d+)/'], '[img=$2x$3]$1', '[/img]'); self::tagToBBCode($doc, 'img', ['src' => '/(.+)/'], '[img]$1', '[/img]'); @@ -344,12 +357,15 @@ class HTML "[/", "[list]", "[list=1]", - "[*]"], $message + "[*]"], + $message ); } while ($message != $oldmessage); $message = str_replace( - ['[b][b]', '[/b][/b]', '[i][i]', '[/i][/i]'], ['[b]', '[/b]', '[i]', '[/i]'], $message + ['[b][b]', '[/b][/b]', '[i][i]', '[/i][/i]'], + ['[b]', '[/b]', '[i]', '[/i]'], + $message ); // Handling Yahoo style of mails @@ -424,7 +440,8 @@ class HTML foreach ($matches as $match) { $body = preg_replace_callback( - $match, function ($match) use ($basepath) { + $match, + function ($match) use ($basepath) { return self::qualifyURLsSub($match, $basepath); }, $body @@ -688,4 +705,327 @@ class HTML return $markdown; } + + /** + * @brief Convert video HTML to BBCode tags + * + * @param string $s + */ + public static function toBBCodeVideo($s) + { + $s = preg_replace( + '#]+>(.*?)https?://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+)(.*?)#ism', + '[youtube]$2[/youtube]', + $s + ); + + $s = preg_replace( + '#](.*?)https?://www.youtube.com/embed/([A-Za-z0-9\-_=]+)(.*?)#ism', + '[youtube]$2[/youtube]', + $s + ); + + $s = preg_replace( + '#](.*?)https?://player.vimeo.com/video/([0-9]+)(.*?)#ism', + '[vimeo]$2[/vimeo]', + $s + ); + + return $s; + } + + /** + * transform link href and img src from relative to absolute + * + * @param string $text + * @param string $base base url + * @return string + */ + public static function relToAbs($text, $base) + { + if (empty($base)) { + return $text; + } + + $base = rtrim($base, '/'); + + $base2 = $base . "/"; + + // Replace links + $pattern = "/]*) href=\"(?!http|https|\/)([^\"]*)\"/"; + $replace = "'; + } + + /** + * Loader for infinite scrolling + * @return string html for loader + */ + public static function scrollLoader() + { + $tpl = Renderer::getMarkupTemplate("scroll_loader.tpl"); + return Renderer::replaceMacros($tpl, [ + 'wait' => L10n::t('Loading more entries...'), + 'end' => L10n::t('The end') + ]); + } + + /** + * Get html for contact block. + * + * @template contact_block.tpl + * @hook contact_block_end (contacts=>array, output=>string) + * @return string + */ + public static function contactBlock() + { + $o = ''; + $a = get_app(); + + $shown = PConfig::get($a->profile['uid'], 'system', 'display_friend_count', 24); + if ($shown == 0) { + return; + } + + if (!is_array($a->profile) || $a->profile['hide-friends']) { + return $o; + } + + $r = q("SELECT COUNT(*) AS `total` FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `blocked` + AND NOT `pending` AND NOT `hidden` AND NOT `archive` + AND `network` IN ('%s', '%s', '%s')", + intval($a->profile['uid']), + DBA::escape(Protocol::DFRN), + DBA::escape(Protocol::OSTATUS), + DBA::escape(Protocol::DIASPORA) + ); + + if (DBA::isResult($r)) { + $total = intval($r[0]['total']); + } + + if (!$total) { + $contacts = L10n::t('No contacts'); + $micropro = null; + } else { + // Splitting the query in two parts makes it much faster + $r = q("SELECT `id` FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `blocked` + AND NOT `pending` AND NOT `hidden` AND NOT `archive` + AND `network` IN ('%s', '%s', '%s') + ORDER BY RAND() LIMIT %d", + intval($a->profile['uid']), + DBA::escape(Protocol::DFRN), + DBA::escape(Protocol::OSTATUS), + DBA::escape(Protocol::DIASPORA), + intval($shown) + ); + + if (DBA::isResult($r)) { + $contacts = []; + foreach ($r as $contact) { + $contacts[] = $contact["id"]; + } + + $r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `thumb`, `network` FROM `contact` WHERE `id` IN (%s)", + DBA::escape(implode(",", $contacts)) + ); + + if (DBA::isResult($r)) { + $contacts = L10n::tt('%d Contact', '%d Contacts', $total); + $micropro = []; + foreach ($r as $rr) { + $micropro[] = self::micropro($rr, true, 'mpfriend'); + } + } + } + } + + $tpl = Renderer::getMarkupTemplate('contact_block.tpl'); + $o = Renderer::replaceMacros($tpl, [ + '$contacts' => $contacts, + '$nickname' => $a->profile['nickname'], + '$viewcontacts' => L10n::t('View Contacts'), + '$micropro' => $micropro, + ]); + + $arr = ['contacts' => $r, 'output' => $o]; + + Addon::callHooks('contact_block_end', $arr); + + return $o; + } + + /** + * @brief Format contacts as picture links or as texxt links + * + * @param array $contact Array with contacts which contains an array with + * int 'id' => The ID of the contact + * int 'uid' => The user ID of the user who owns this data + * string 'name' => The name of the contact + * string 'url' => The url to the profile page of the contact + * string 'addr' => The webbie of the contact (e.g.) username@friendica.com + * string 'network' => The network to which the contact belongs to + * string 'thumb' => The contact picture + * string 'click' => js code which is performed when clicking on the contact + * @param boolean $redirect If true try to use the redir url if it's possible + * @param string $class CSS class for the + * @param boolean $textmode If true display the contacts as text links + * if false display the contacts as picture links + + * @return string Formatted html + */ + public static function micropro($contact, $redirect = false, $class = '', $textmode = false) + { + // Use the contact URL if no address is available + if (!x($contact, "addr")) { + $contact["addr"] = $contact["url"]; + } + + $url = $contact['url']; + $sparkle = ''; + $redir = false; + + if ($redirect) { + $url = Contact::magicLink($contact['url']); + if (strpos($url, 'redir/') === 0) { + $sparkle = ' sparkle'; + } + } + + // If there is some js available we don't need the url + if (x($contact, 'click')) { + $url = ''; + } + + return Renderer::replaceMacros(Renderer::getMarkupTemplate(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'), [ + '$click' => defaults($contact, 'click', ''), + '$class' => $class, + '$url' => $url, + '$photo' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB), + '$name' => $contact['name'], + 'title' => $contact['name'] . ' [' . $contact['addr'] . ']', + '$parkle' => $sparkle, + '$redir' => $redir + ]); + } + + /** + * Search box. + * + * @param string $s Search query. + * @param string $id HTML id + * @param string $url Search url. + * @param bool $save Show save search button. + * @param bool $aside Display the search widgit aside. + * + * @return string Formatted HTML. + */ + public static function search($s, $id = 'search-box', $url = 'search', $save = false, $aside = true) + { + $mode = 'text'; + + if (strpos($s, '#') === 0) { + $mode = 'tag'; + } + $save_label = $mode === 'text' ? L10n::t('Save') : L10n::t('Follow'); + + $values = [ + '$s' => htmlspecialchars($s), + '$id' => $id, + '$action_url' => $url, + '$search_label' => L10n::t('Search'), + '$save_label' => $save_label, + '$savedsearch' => local_user() && Feature::isEnabled(local_user(), 'savedsearch'), + '$search_hint' => L10n::t('@name, !forum, #tags, content'), + '$mode' => $mode + ]; + + if (!$aside) { + $values['$searchoption'] = [ + L10n::t("Full Text"), + L10n::t("Tags"), + L10n::t("Contacts")]; + + if (Config::get('system', 'poco_local_search')) { + $values['$searchoption'][] = L10n::t("Forums"); + } + } + + return Renderer::replaceMacros(Renderer::getMarkupTemplate('searchbox.tpl'), $values); + } + + /** + * Replace naked text hyperlink with HTML formatted hyperlink + * + * @param string $s + */ + public static function toLink($s) + { + $s = preg_replace("/(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\'\%\$\!\+]*)/", ' $1', $s); + $s = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $s); + return $s; + } + + /** + * Given a HTML text and a set of filtering reasons, adds a content hiding header with the provided reasons + * + * Reasons are expected to have been translated already. + * + * @param string $html + * @param array $reasons + * @return string + */ + public static function applyContentFilter($html, array $reasons) + { + if (count($reasons)) { + $tpl = Renderer::getMarkupTemplate('wall/content_filter.tpl'); + $html = Renderer::replaceMacros($tpl, [ + '$reasons' => $reasons, + '$rnd' => random_string(8), + '$openclose' => L10n::t('Click to open/close'), + '$html' => $html + ]); + } + + return $html; + } + + /** + * replace html amp entity with amp char + * @param string $s + * @return string + */ + public static function unamp($s) + { + return str_replace('&', '&', $s); + } } diff --git a/src/Model/Profile.php b/src/Model/Profile.php index 2cd3f7a86c..81a7630bbd 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -8,6 +8,7 @@ use Friendica\App; use Friendica\Content\Feature; use Friendica\Content\ForumManager; use Friendica\Content\Text\BBCode; +use Friendica\Content\Text\HTML; use Friendica\Core\Addon; use Friendica\Core\Cache; use Friendica\Core\Config; @@ -467,7 +468,7 @@ class Profile $updated = ''; $contacts = 0; if (!$block) { - $contact_block = contact_block(); + $contact_block = HTML::contactBlock(); if (is_array($a->profile) && !$a->profile['hide-friends']) { $r = q( @@ -785,11 +786,11 @@ class Profile } if ($a->profile['homepage']) { - $profile['homepage'] = [L10n::t('Homepage:'), linkify($a->profile['homepage'])]; + $profile['homepage'] = [L10n::t('Homepage:'), HTML::toLink($a->profile['homepage'])]; } if ($a->profile['hometown']) { - $profile['hometown'] = [L10n::t('Hometown:'), linkify($a->profile['hometown'])]; + $profile['hometown'] = [L10n::t('Hometown:'), HTML::toLink($a->profile['hometown'])]; } if ($a->profile['pub_keywords']) { diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 33df28d92b..8a2b21745d 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -2500,9 +2500,9 @@ class DFRN /// @todo Do we really need this check for HTML elements? (It was copied from the old function) if ((strpos($item['body'], '<') !== false) && (strpos($item['body'], '>') !== false)) { $base_url = get_app()->getBaseURL(); - $item['body'] = reltoabs($item['body'], $base_url); + $item['body'] = HTML::relToAbs($item['body'], $base_url); - $item['body'] = html2bb_video($item['body']); + $item['body'] = HTML::toBBCodeVideo($item['body']); $item['body'] = OEmbed::HTML2BBCode($item['body']);