diff --git a/src/Content/OEmbed.php b/src/Content/OEmbed.php index 445c52ced0..9af01b76da 100644 --- a/src/Content/OEmbed.php +++ b/src/Content/OEmbed.php @@ -22,10 +22,9 @@ namespace Friendica\Content; use DOMDocument; -use DOMNode; -use DOMText; use DOMXPath; use Exception; +use Friendica\Content\Text\BBCode; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Hook; use Friendica\Core\Renderer; @@ -49,32 +48,15 @@ use Friendica\Util\Strings; */ class OEmbed { - /** - * Callback for fetching URL, checking allowance and returning formatted HTML - * - * @param array $matches - * @return string Formatted HTML - */ - public static function replaceCallback(array $matches): string - { - $embedurl = $matches[1]; - $j = self::fetchURL($embedurl, !self::isAllowedURL($embedurl)); - $s = self::formatObject($j); - - return $s; - } - /** * Get data from an URL to embed its content. * - * @param string $embedurl The URL from which the data should be fetched. - * @param bool $no_rich_type If set to true rich type content won't be fetched. - * @param bool $use_parseurl Use the "ParseUrl" functionality to add additional data + * @param string $embedurl The URL from which the data should be fetched. * * @return \Friendica\Object\OEmbed * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function fetchURL(string $embedurl, bool $no_rich_type = false, bool $use_parseurl = true): \Friendica\Object\OEmbed + private static function fetchURL(string $embedurl): \Friendica\Object\OEmbed { $embedurl = trim($embedurl, '\'"'); @@ -119,7 +101,7 @@ class OEmbed $href = str_replace(['http://www.youtube.com/', 'http://player.vimeo.com/'], ['https://www.youtube.com/', 'https://player.vimeo.com/'], $href); $result = DI::httpClient()->fetchFull($href . '&maxwidth=' . $a->getThemeInfoValue('videowidth')); - if ($result->getReturnCode() === 200) { + if ($result->isSuccess()) { $json_string = $result->getBodyString(); break; } @@ -157,57 +139,55 @@ class OEmbed } // Improve the OEmbed data with data from OpenGraph, Twitter cards and other sources - if ($use_parseurl) { - $data = ParseUrl::getSiteinfoCached($embedurl, false); + $data = ParseUrl::getSiteinfoCached($embedurl); - if (($oembed->type == 'error') && empty($data['title']) && empty($data['text'])) { - return $oembed; - } + if (($oembed->type == 'error') && empty($data['title']) && empty($data['text'])) { + return $oembed; + } - if ($no_rich_type || ($oembed->type == 'error')) { - $oembed->html = ''; - $oembed->type = $data['type']; + if (!self::isAllowedURL($embedurl) || ($oembed->type == 'error')) { + $oembed->html = ''; + $oembed->type = $data['type']; - if ($oembed->type == 'photo') { - if (!empty($data['images'])) { - $oembed->url = $data['images'][0]['src']; - $oembed->width = $data['images'][0]['width']; - $oembed->height = $data['images'][0]['height']; - } else { - $oembed->type = 'link'; - } + if ($oembed->type == 'photo') { + if (!empty($data['images'])) { + $oembed->url = $data['images'][0]['src']; + $oembed->width = $data['images'][0]['width']; + $oembed->height = $data['images'][0]['height']; + } else { + $oembed->type = 'link'; } } + } - if (!empty($data['title'])) { - $oembed->title = $data['title']; - } + if (!empty($data['title'])) { + $oembed->title = $data['title']; + } - if (!empty($data['text'])) { - $oembed->description = $data['text']; - } + if (!empty($data['text'])) { + $oembed->description = $data['text']; + } - if (!empty($data['publisher_name'])) { - $oembed->provider_name = $data['publisher_name']; - } + if (!empty($data['publisher_name'])) { + $oembed->provider_name = $data['publisher_name']; + } - if (!empty($data['publisher_url'])) { - $oembed->provider_url = $data['publisher_url']; - } + if (!empty($data['publisher_url'])) { + $oembed->provider_url = $data['publisher_url']; + } - if (!empty($data['author_name'])) { - $oembed->author_name = $data['author_name']; - } + if (!empty($data['author_name'])) { + $oembed->author_name = $data['author_name']; + } - if (!empty($data['author_url'])) { - $oembed->author_url = $data['author_url']; - } + if (!empty($data['author_url'])) { + $oembed->author_url = $data['author_url']; + } - if (!empty($data['images']) && ($oembed->type != 'photo')) { - $oembed->thumbnail_url = $data['images'][0]['src']; - $oembed->thumbnail_width = $data['images'][0]['width']; - $oembed->thumbnail_height = $data['images'][0]['height']; - } + if (!empty($data['images']) && ($oembed->type != 'photo')) { + $oembed->thumbnail_url = $data['images'][0]['src']; + $oembed->thumbnail_width = $data['images'][0]['width']; + $oembed->thumbnail_height = $data['images'][0]['height']; } Hook::callAll('oembed_fetch_url', $embedurl, $oembed); @@ -219,9 +199,10 @@ class OEmbed * Returns a formatted string from OEmbed object * * @param \Friendica\Object\OEmbed $oembed + * @param int $uriid * @return string */ - private static function formatObject(\Friendica\Object\OEmbed $oembed): string + private static function formatObject(\Friendica\Object\OEmbed $oembed, int $uriid): string { $ret = '
'; @@ -241,7 +222,7 @@ class OEmbed '$escapedhtml' => base64_encode($oembed->html), '$tw' => $tw, '$th' => $th, - '$turl' => $oembed->thumbnail_url, + '$turl' => BBCode::proxyUrl($oembed->thumbnail_url, BBCode::INTERNAL, $uriid, Proxy::SIZE_SMALL), ]); } else { $ret = $oembed->html; @@ -249,14 +230,14 @@ class OEmbed break; case 'photo': - $ret .= ''; + $ret .= ''; break; case 'link': break; case 'rich': - $ret .= Proxy::proxifyHtml($oembed->html); + $ret .= Proxy::proxifyHtml($oembed->html, $uriid); break; } @@ -294,12 +275,21 @@ class OEmbed $ret .= '' . $oembed->embed_url . ''; } $ret .= ""; + if ($oembed->type == 'link') { + if (!empty($oembed->thumbnail_url)) { + $ret .= ''; + } + if (!empty($oembed->description)) { + $ret .= '

' . $oembed->description . '

'; + } + } } elseif (!strpos($oembed->html, $oembed->embed_url)) { // add for html2bbcode conversion $ret .= '' . $oembed->title . ''; } $ret .= '
'; +$test = Proxy::proxifyHtml($ret, $uriid); return str_replace("\n", "", $ret); } @@ -308,51 +298,19 @@ class OEmbed * Converts BBCode to HTML code * * @param string $text + * @param int $uriid * @return string */ - public static function BBCode2HTML(string $text): string + public static function BBCode2HTML(string $text, int $uriid): string { - 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); - } - - /** - * Find .... - * and replace it with [embed]url[/embed] - * - * @param string $text - * @return string - */ - public static function HTML2BBCode(string $text): string - { - // start parser only if 'oembed' is in text - if (strpos($text, 'oembed')) { - // convert non ascii chars to html entities - $html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text)); - - // If it doesn't parse at all, just return the text. - $dom = new DOMDocument(); - if (!@$dom->loadHTML($html_text)) { - return $text; - } - $xpath = new DOMXPath($dom); - - $xattr = self::buildXPath('class', 'oembed'); - $entries = $xpath->query("//div[$xattr]"); - - $xattr = "@rel='oembed'"; //oe_build_xpath("rel","oembed"); - foreach ($entries as $e) { - $href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue; - if (!is_null($href)) { - $e->parentNode->replaceChild(new DOMText('[embed]' . $href . '[/embed]'), $e); - } - } - return self::getInnerHTML($dom->getElementsByTagName('body')->item(0)); - } else { + if (!preg_match_all("/\[embed\](.+?)\[\/embed\]/is", $text, $matches, PREG_SET_ORDER)) { return $text; } + foreach ($matches as $match) { + $data = self::fetchURL($match[1]); + $text = str_replace($match[0], self::formatObject($data, $uriid), $text); + } + return $text; } /** @@ -373,26 +331,25 @@ class OEmbed return false; } - $str_allowed = DI::config()->get('system', 'allowed_oembed', ''); - if (empty($str_allowed)) { + $allowed = DI::config()->get('system', 'allowed_oembed', ''); + if (empty($allowed)) { return false; } - $allowed = explode(',', $str_allowed); - - return Network::isDomainMatch($domain, $allowed); + return Network::isDomainMatch($domain, explode(',', $allowed)); } /** * Returns a formatted HTML code from given URL and sets optional title * * @param string $url URL to fetch - * @param string $title Optional title (default: what comes from OEmbed object) + * @param string $title title (default: what comes from OEmbed object) + * @param int $uriid * @return string Formatted HTML */ - public static function getHTML(string $url, string $title = ''): string + public static function getHTML(string $url, string $title, int $uriid): string { - $o = self::fetchURL($url, !self::isAllowedURL($url)); + $o = self::fetchURL($url); if (!is_object($o) || property_exists($o, 'type') && $o->type == 'error') { throw new Exception('OEmbed failed for URL: ' . $url); @@ -402,74 +359,8 @@ class OEmbed $o->title = $title; } - $html = self::formatObject($o); + $html = self::formatObject($o, $uriid); return $html; } - - /** - * Generates the iframe HTML for an oembed attachment. - * - * Width and height are given by the remote, and are regularly too small for - * the generated iframe. - * - * The width is entirely discarded for the actual width of the post, while fixed - * height is used as a starting point before the inevitable resizing. - * - * Since the iframe is automatically resized on load, there are no need for ugly - * and impractical scrollbars. - * - * @todo This function is currently unused until someoneā„¢ adds support for a separate OEmbed domain - * - * @param string $src Original remote URL to embed - * @param string $width - * @param string $height - * @return string Formatted HTML - * - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @see oembed_format_object() - */ - private static function iframe(string $src, string $width, string $height): string - { - if (!$height || strstr($height, '%')) { - $height = '200'; - } - $width = '100%'; - - $src = DI::baseUrl() . '/oembed/' . Strings::base64UrlEncode($src); - return ''; - } - - /** - * Generates attribute search XPath string - * - * Generates an XPath query to select elements whose provided attribute contains - * the provided value in a space-separated list. - * - * @param string $attr Name of the attribute to search - * @param string $value Value to search in a space-separated list - * @return string - */ - private static function buildXPath(string $attr, $value): string - { - // https://www.westhoffswelt.de/blog/2009/6/9/select-html-elements-with-more-than-one-css-class-using-xpath - return "contains(normalize-space(@$attr), ' $value ') or substring(normalize-space(@$attr), 1, string-length('$value') + 1) = '$value ' or substring(normalize-space(@$attr), string-length(@$attr) - string-length('$value')) = ' $value' or @$attr = '$value'"; - } - - /** - * Returns the inner XML string of a provided DOMNode - * - * @param DOMNode $node - * @return string - */ - private static function getInnerHTML(DOMNode $node): string - { - $innerHTML = ''; - $children = $node->childNodes; - foreach ($children as $child) { - $innerHTML .= $child->ownerDocument->saveXML($child); - } - return $innerHTML; - } - } diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index f5bba8ce42..877e3e2e55 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -310,7 +310,7 @@ class BBCode return trim($text); } - private static function proxyUrl(string $image, int $simplehtml = self::INTERNAL, int $uriid = 0, string $size = ''): string + public static function proxyUrl(string $image, int $simplehtml = self::INTERNAL, int $uriid = 0, string $size = ''): string { // Only send proxied pictures to API and for internal display if (!in_array($simplehtml, [self::INTERNAL, self::MASTODON_API, self::TWITTER_API])) { @@ -453,7 +453,7 @@ class BBCode $return = ''; try { if ($tryoembed && OEmbed::isAllowedURL($data['url'])) { - $return = OEmbed::getHTML($data['url'], $data['title']); + $return = OEmbed::getHTML($data['url'], $data['title'], $uriid); } else { throw new Exception('OEmbed is disabled for this attachment.'); } @@ -1358,12 +1358,12 @@ class BBCode * $match[1] = $url * $match[2] = $title or absent */ - $try_oembed_callback = function (array $match) { + $try_oembed_callback = function (array $match) use ($uriid) { $url = $match[1]; $title = $match[2] ?? ''; try { - $return = OEmbed::getHTML($url, $title); + $return = OEmbed::getHTML($url, $title, $uriid); } catch (Exception $ex) { $return = $match[0]; } @@ -1810,7 +1810,7 @@ class BBCode } // oembed tag - $text = OEmbed::BBCode2HTML($text); + $text = OEmbed::BBCode2HTML($text, $uriid); // Avoid triple linefeeds through oembed $text = str_replace("


", "

", $text); @@ -2058,9 +2058,6 @@ class BBCode // Default iframe allowed domains/path $allowedIframeDomains = [ - DI::baseUrl()->getHost() - . (DI::baseUrl()->getPath() ? '/' . DI::baseUrl()->getPath() : '') - . '/oembed/', # The path part has to change with the source in Content\Oembed::iframe 'www.youtube.com/embed/', 'player.vimeo.com/video/', ]; diff --git a/src/Module/Oembed.php b/src/Module/Oembed.php deleted file mode 100644 index 68e13a2e86..0000000000 --- a/src/Module/Oembed.php +++ /dev/null @@ -1,74 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\Content; -use Friendica\Core\System; -use Friendica\DI; -use Friendica\Util\Strings; - -/** - * Oembed module - * - * Displays stored embed content based on a base64 hash of a remote URL - * - * Example: /oembed/aHR0cHM6Ly9... - * - * @author Hypolite Petovan - */ -class Oembed extends BaseModule -{ - protected function content(array $request = []): string - { - // Unused form: /oembed/b2h?url=... - if (DI::args()->getArgv()[1] == 'b2h') { - $url = ["", trim(hex2bin($_REQUEST['url']))]; - echo Content\OEmbed::replaceCallback($url); - System::exit(); - } - - // Unused form: /oembed/h2b?text=... - if (DI::args()->getArgv()[1] == 'h2b') { - $text = trim(hex2bin($_REQUEST['text'])); - echo Content\OEmbed::HTML2BBCode($text); - System::exit(); - } - - // @TODO: Replace with parameter from router - if (DI::args()->getArgc() == 2) { - echo ''; - $url = Strings::base64UrlDecode(DI::args()->getArgv()[1]); - $j = Content\OEmbed::fetchURL($url); - - // workaround for media.ccc.de (and any other endpoint that return size 0) - if (substr($j->html, 0, 7) == "html, 'width="0"')) { - $j->html = '' . $j->html; - $j->html = str_replace('width="0"', '', $j->html); - $j->html = str_replace('height="0"', '', $j->html); - } - echo $j->html; - echo ''; - } - System::exit(); - } -} diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index 1287160576..7c9a058b43 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -99,8 +99,6 @@ class ParseUrl * Search for cached embeddable data of an url otherwise fetch it * * @param string $url The url of the page which should be scraped - * @param bool $do_oembed The false option is used by the function fetch_oembed() - * to avoid endless loops * * @return array which contains needed data for embedding * string 'url' => The url of the parsed page @@ -115,7 +113,7 @@ class ParseUrl * @see ParseUrl::getSiteinfo() for more information about scraping * embeddable content */ - public static function getSiteinfoCached(string $url, bool $do_oembed = true): array + public static function getSiteinfoCached(string $url): array { if (empty($url)) { return [ @@ -127,14 +125,14 @@ class ParseUrl $urlHash = hash('sha256', $url); $parsed_url = DBA::selectFirst('parsed_url', ['content'], - ['url_hash' => $urlHash, 'oembed' => $do_oembed] + ['url_hash' => $urlHash, 'oembed' => false] ); if (!empty($parsed_url['content'])) { $data = unserialize($parsed_url['content']); return $data; } - $data = self::getSiteinfo($url, $do_oembed); + $data = self::getSiteinfo($url); $expires = $data['expires']; @@ -144,7 +142,7 @@ class ParseUrl 'parsed_url', [ 'url_hash' => $urlHash, - 'oembed' => $do_oembed, + 'oembed' => false, 'url' => $url, 'content' => serialize($data), 'created' => DateTimeFormat::utcNow(), @@ -194,7 +192,7 @@ class ParseUrl * * @endverbatim */ - public static function getSiteinfo(string $url, bool $do_oembed = true, int $count = 1): array + public static function getSiteinfo(string $url, int $count = 1): array { if (empty($url)) { return [ @@ -254,41 +252,6 @@ class ParseUrl $body = $curlResult->getBodyString(); - if ($do_oembed) { - $oembed_data = OEmbed::fetchURL($url, false, false); - - if (!empty($oembed_data->type)) { - if (!in_array($oembed_data->type, ['error', 'rich', 'image', 'video', 'audio', ''])) { - $siteinfo['type'] = $oembed_data->type; - } - - // See https://github.com/friendica/friendica/pull/5763#discussion_r217913178 - if ($siteinfo['type'] != 'photo') { - if (!empty($oembed_data->title)) { - $siteinfo['title'] = trim($oembed_data->title); - } - if (!empty($oembed_data->description)) { - $siteinfo['text'] = trim($oembed_data->description); - } - if (!empty($oembed_data->author_name)) { - $siteinfo['author_name'] = trim($oembed_data->author_name); - } - if (!empty($oembed_data->author_url)) { - $siteinfo['author_url'] = Network::sanitizeUrl($oembed_data->author_url); - } - if (!empty($oembed_data->provider_name)) { - $siteinfo['publisher_name'] = trim($oembed_data->provider_name); - } - if (!empty($oembed_data->provider_url)) { - $siteinfo['publisher_url'] = Network::sanitizeUrl($oembed_data->provider_url); - } - if (!empty($oembed_data->thumbnail_url)) { - $siteinfo['image'] = $oembed_data->thumbnail_url; - } - } - } - } - $charset = ''; try { // Look for a charset, first in headers @@ -351,7 +314,7 @@ class ParseUrl } } if ($content != '') { - $siteinfo = self::getSiteinfo($content, $do_oembed, ++$count); + $siteinfo = self::getSiteinfo($content, ++$count); return $siteinfo; } } diff --git a/src/Util/Proxy.php b/src/Util/Proxy.php index 9a2d25c680..17b71ddd88 100644 --- a/src/Util/Proxy.php +++ b/src/Util/Proxy.php @@ -21,8 +21,8 @@ namespace Friendica\Util; +use Friendica\Content\Text\BBCode; use Friendica\Core\Logger; -use Friendica\Core\System; use Friendica\DI; use GuzzleHttp\Psr7\Uri; @@ -133,15 +133,24 @@ class Proxy * proxy storage directory. * * @param string $html Un-proxified HTML code + * @param int $uriid * * @return string Proxified HTML code * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function proxifyHtml(string $html): string + public static function proxifyHtml(string $html, int $uriid): string { $html = str_replace(Strings::normaliseLink(DI::baseUrl()) . '/', DI::baseUrl() . '/', $html); - return preg_replace_callback('/(]*src *= *["\'])([^"\']+)(["\'][^>]*>)/siU', [self::class, 'replaceUrl'], $html); + if (!preg_match_all('/(]*src *= *["\'])([^"\']+)(["\'][^>]*>)/siU', $html, $matches, PREG_SET_ORDER)) { + return $html; + } + + foreach ($matches as $match) { + $html = str_replace($match[0], self::replaceUrl($match, $uriid), $html); + } + + return $html; } /** @@ -193,7 +202,7 @@ class Proxy * @return string Proxified HTML image tag * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function replaceUrl(array $matches): string + private static function replaceUrl(array $matches, int $uriid): string { // if the picture seems to be from another picture cache then take the original source $queryvar = self::parseQuery($matches[2]); @@ -208,7 +217,7 @@ class Proxy } // Return proxified HTML - return $matches[1] . self::proxifyUrl(htmlspecialchars_decode($matches[2])) . $matches[3]; + return $matches[1] . BBCode::proxyUrl(htmlspecialchars_decode($matches[2]), BBCode::INTERNAL, $uriid, Proxy::SIZE_MEDIUM) . $matches[3]; } public static function getPixelsFromSize(string $size): int diff --git a/static/routes.config.php b/static/routes.config.php index 146255adc6..77d04f92c1 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -557,11 +557,6 @@ return [ '/objects/{guid}[/{activity}]' => [Module\ActivityPub\Objects::class, [R::GET]], - '/oembed' => [ - '/b2h' => [Module\Oembed::class, [R::GET]], - '/h2b' => [Module\Oembed::class, [R::GET]], - '/{hash}' => [Module\Oembed::class, [R::GET]], - ], '/outbox/{nickname}' => [Module\ActivityPub\Outbox::class, [R::GET, R::POST]], '/owa' => [Module\Owa::class, [R::GET]], '/openid' => [Module\Security\OpenID::class, [R::GET]], diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 9d71014a04..aeaa39fc86 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2024.03-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-02-19 05:46+0000\n" +"POT-Creation-Date: 2024-02-24 15:29+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -71,11 +71,11 @@ msgstr "" #: src/Module/Settings/Display.php:90 src/Module/Settings/Display.php:199 #: src/Module/Settings/Profile/Photo/Crop.php:165 #: src/Module/Settings/Profile/Photo/Index.php:110 -#: src/Module/Settings/RemoveMe.php:119 src/Module/Settings/UserExport.php:80 +#: src/Module/Settings/RemoveMe.php:119 src/Module/Settings/UserExport.php:78 #: src/Module/Settings/UserExport.php:114 -#: src/Module/Settings/UserExport.php:215 -#: src/Module/Settings/UserExport.php:235 -#: src/Module/Settings/UserExport.php:300 src/Module/User/Delegation.php:154 +#: src/Module/Settings/UserExport.php:213 +#: src/Module/Settings/UserExport.php:233 +#: src/Module/Settings/UserExport.php:298 src/Module/User/Delegation.php:154 #: src/Module/User/Import.php:84 src/Module/User/Import.php:91 msgid "Permission denied." msgstr "" @@ -302,7 +302,7 @@ msgstr "" #: src/Module/Calendar/Event/Form.php:250 src/Module/Contact/Advanced.php:132 #: src/Module/Contact/Profile.php:364 #: src/Module/Debug/ActivityPubConversion.php:140 -#: src/Module/Debug/Babel.php:313 src/Module/Debug/Localtime.php:64 +#: src/Module/Debug/Babel.php:315 src/Module/Debug/Localtime.php:64 #: src/Module/Debug/Probe.php:54 src/Module/Debug/WebFinger.php:51 #: src/Module/FriendSuggest.php:145 src/Module/Install.php:234 #: src/Module/Install.php:274 src/Module/Install.php:309 @@ -1080,7 +1080,7 @@ msgstr "" msgid "Email" msgstr "" -#: src/Content/ContactSelector.php:130 src/Module/Debug/Babel.php:307 +#: src/Content/ContactSelector.php:130 src/Module/Debug/Babel.php:309 msgid "Diaspora" msgstr "" @@ -2174,14 +2174,6 @@ msgstr "" msgid "Site map" msgstr "" -#: src/Content/OEmbed.php:316 -msgid "Embedding disabled" -msgstr "" - -#: src/Content/OEmbed.php:440 -msgid "Embedded content" -msgstr "" - #: src/Content/Pager.php:216 msgid "first" msgstr "" @@ -2467,7 +2459,7 @@ msgid "Matrix:" msgstr "" #: src/Content/Widget/VCard.php:121 src/Model/Event.php:82 -#: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963 +#: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:960 #: src/Model/Profile.php:375 src/Module/Contact/Profile.php:406 #: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187 #: src/Module/Profile/Profile.php:221 @@ -3343,12 +3335,12 @@ msgid "l F d, Y \\@ g:i A \\G\\M\\TP (e)" msgstr "" #: src/Model/Event.php:75 src/Model/Event.php:92 src/Model/Event.php:469 -#: src/Model/Event.php:945 +#: src/Model/Event.php:942 msgid "Starts:" msgstr "" #: src/Model/Event.php:78 src/Model/Event.php:98 src/Model/Event.php:470 -#: src/Model/Event.php:949 +#: src/Model/Event.php:946 msgid "Finishes:" msgstr "" @@ -3421,20 +3413,20 @@ msgstr "" msgid "g:i A" msgstr "" -#: src/Model/Event.php:964 src/Model/Event.php:966 +#: src/Model/Event.php:961 src/Model/Event.php:963 msgid "Show map" msgstr "" -#: src/Model/Event.php:965 +#: src/Model/Event.php:962 msgid "Hide map" msgstr "" -#: src/Model/Event.php:1058 +#: src/Model/Event.php:1055 #, php-format msgid "%s's birthday" msgstr "" -#: src/Model/Event.php:1059 +#: src/Model/Event.php:1056 #, php-format msgid "Happy Birthday %s" msgstr "" @@ -6157,11 +6149,11 @@ msgstr "" msgid "Failed to remove event" msgstr "" -#: src/Module/Calendar/Event/API.php:186 src/Module/Calendar/Event/API.php:188 +#: src/Module/Calendar/Event/API.php:187 src/Module/Calendar/Event/API.php:189 msgid "Event can not end before it has started." msgstr "" -#: src/Module/Calendar/Event/API.php:195 src/Module/Calendar/Event/API.php:197 +#: src/Module/Calendar/Event/API.php:196 src/Module/Calendar/Event/API.php:198 msgid "Event title and start time are required." msgstr "" @@ -7072,33 +7064,33 @@ msgstr "" msgid "Not available." msgstr "" -#: src/Module/Conversation/Network.php:202 +#: src/Module/Conversation/Network.php:200 msgid "No such circle" msgstr "" -#: src/Module/Conversation/Network.php:206 +#: src/Module/Conversation/Network.php:204 #, php-format msgid "Circle: %s" msgstr "" -#: src/Module/Conversation/Network.php:225 +#: src/Module/Conversation/Network.php:223 #, php-format msgid "Error %d (%s) while fetching the timeline." msgstr "" -#: src/Module/Conversation/Network.php:302 +#: src/Module/Conversation/Network.php:300 msgid "Network feed not available." msgstr "" -#: src/Module/Conversation/Timeline.php:194 +#: src/Module/Conversation/Timeline.php:196 msgid "Own Contacts" msgstr "" -#: src/Module/Conversation/Timeline.php:198 +#: src/Module/Conversation/Timeline.php:200 msgid "Include" msgstr "" -#: src/Module/Conversation/Timeline.php:199 +#: src/Module/Conversation/Timeline.php:201 msgid "Hide" msgstr "" @@ -7130,7 +7122,7 @@ msgid "Result Item" msgstr "" #: src/Module/Debug/ActivityPubConversion.php:129 -#: src/Module/Debug/Babel.php:293 src/Module/Moderation/Item/Source.php:87 +#: src/Module/Debug/Babel.php:294 src/Module/Moderation/Item/Source.php:87 #: src/Module/Security/TwoFactor/Verify.php:98 msgid "Error" msgid_plural "Errors" @@ -7141,179 +7133,179 @@ msgstr[1] "" msgid "Source activity" msgstr "" -#: src/Module/Debug/Babel.php:51 +#: src/Module/Debug/Babel.php:52 msgid "Source input" msgstr "" -#: src/Module/Debug/Babel.php:57 +#: src/Module/Debug/Babel.php:58 msgid "BBCode::toPlaintext" msgstr "" -#: src/Module/Debug/Babel.php:63 +#: src/Module/Debug/Babel.php:64 msgid "BBCode::convert (raw HTML)" msgstr "" -#: src/Module/Debug/Babel.php:68 +#: src/Module/Debug/Babel.php:69 msgid "BBCode::convert (hex)" msgstr "" -#: src/Module/Debug/Babel.php:73 +#: src/Module/Debug/Babel.php:74 msgid "BBCode::convert" msgstr "" -#: src/Module/Debug/Babel.php:79 +#: src/Module/Debug/Babel.php:80 msgid "BBCode::convert => HTML::toBBCode" msgstr "" -#: src/Module/Debug/Babel.php:85 +#: src/Module/Debug/Babel.php:86 msgid "BBCode::toMarkdown" msgstr "" -#: src/Module/Debug/Babel.php:91 +#: src/Module/Debug/Babel.php:92 msgid "BBCode::toMarkdown => Markdown::convert (raw HTML)" msgstr "" -#: src/Module/Debug/Babel.php:95 +#: src/Module/Debug/Babel.php:96 msgid "BBCode::toMarkdown => Markdown::convert" msgstr "" -#: src/Module/Debug/Babel.php:101 +#: src/Module/Debug/Babel.php:102 msgid "BBCode::toMarkdown => Markdown::toBBCode" msgstr "" -#: src/Module/Debug/Babel.php:107 +#: src/Module/Debug/Babel.php:108 msgid "BBCode::toMarkdown => Markdown::convert => HTML::toBBCode" msgstr "" -#: src/Module/Debug/Babel.php:115 +#: src/Module/Debug/Babel.php:116 msgid "Item Body" msgstr "" -#: src/Module/Debug/Babel.php:119 +#: src/Module/Debug/Babel.php:120 msgid "Item Tags" msgstr "" -#: src/Module/Debug/Babel.php:125 +#: src/Module/Debug/Babel.php:126 msgid "PageInfo::appendToBody" msgstr "" -#: src/Module/Debug/Babel.php:130 +#: src/Module/Debug/Babel.php:131 msgid "PageInfo::appendToBody => BBCode::convert (raw HTML)" msgstr "" -#: src/Module/Debug/Babel.php:134 +#: src/Module/Debug/Babel.php:135 msgid "PageInfo::appendToBody => BBCode::convert" msgstr "" -#: src/Module/Debug/Babel.php:141 +#: src/Module/Debug/Babel.php:142 msgid "Source input (Diaspora format)" msgstr "" -#: src/Module/Debug/Babel.php:150 +#: src/Module/Debug/Babel.php:151 msgid "Source input (Markdown)" msgstr "" -#: src/Module/Debug/Babel.php:156 +#: src/Module/Debug/Babel.php:157 msgid "Markdown::convert (raw HTML)" msgstr "" -#: src/Module/Debug/Babel.php:161 +#: src/Module/Debug/Babel.php:162 msgid "Markdown::convert" msgstr "" -#: src/Module/Debug/Babel.php:167 +#: src/Module/Debug/Babel.php:168 msgid "Markdown::toBBCode" msgstr "" -#: src/Module/Debug/Babel.php:174 +#: src/Module/Debug/Babel.php:175 msgid "Raw HTML input" msgstr "" -#: src/Module/Debug/Babel.php:179 +#: src/Module/Debug/Babel.php:180 msgid "HTML Input" msgstr "" -#: src/Module/Debug/Babel.php:186 +#: src/Module/Debug/Babel.php:187 msgid "HTML Purified (raw)" msgstr "" -#: src/Module/Debug/Babel.php:191 +#: src/Module/Debug/Babel.php:192 msgid "HTML Purified (hex)" msgstr "" -#: src/Module/Debug/Babel.php:196 +#: src/Module/Debug/Babel.php:197 msgid "HTML Purified" msgstr "" -#: src/Module/Debug/Babel.php:202 +#: src/Module/Debug/Babel.php:203 msgid "HTML::toBBCode" msgstr "" -#: src/Module/Debug/Babel.php:208 +#: src/Module/Debug/Babel.php:209 msgid "HTML::toBBCode => BBCode::convert" msgstr "" -#: src/Module/Debug/Babel.php:213 +#: src/Module/Debug/Babel.php:214 msgid "HTML::toBBCode => BBCode::convert (raw HTML)" msgstr "" -#: src/Module/Debug/Babel.php:219 +#: src/Module/Debug/Babel.php:220 msgid "HTML::toBBCode => BBCode::toPlaintext" msgstr "" -#: src/Module/Debug/Babel.php:225 +#: src/Module/Debug/Babel.php:226 msgid "HTML::toMarkdown" msgstr "" -#: src/Module/Debug/Babel.php:231 +#: src/Module/Debug/Babel.php:232 msgid "HTML::toPlaintext" msgstr "" -#: src/Module/Debug/Babel.php:237 +#: src/Module/Debug/Babel.php:238 msgid "HTML::toPlaintext (compact)" msgstr "" -#: src/Module/Debug/Babel.php:255 +#: src/Module/Debug/Babel.php:256 msgid "Decoded post" msgstr "" -#: src/Module/Debug/Babel.php:276 +#: src/Module/Debug/Babel.php:277 msgid "Post array before expand entities" msgstr "" -#: src/Module/Debug/Babel.php:283 +#: src/Module/Debug/Babel.php:284 msgid "Post converted" msgstr "" -#: src/Module/Debug/Babel.php:288 +#: src/Module/Debug/Babel.php:289 msgid "Converted body" msgstr "" -#: src/Module/Debug/Babel.php:294 +#: src/Module/Debug/Babel.php:295 msgid "Twitter addon is absent from the addon/ folder." msgstr "" -#: src/Module/Debug/Babel.php:304 +#: src/Module/Debug/Babel.php:305 msgid "Babel Diagnostic" msgstr "" -#: src/Module/Debug/Babel.php:305 +#: src/Module/Debug/Babel.php:307 msgid "Source text" msgstr "" -#: src/Module/Debug/Babel.php:306 +#: src/Module/Debug/Babel.php:308 msgid "BBCode" msgstr "" -#: src/Module/Debug/Babel.php:308 +#: src/Module/Debug/Babel.php:310 msgid "Markdown" msgstr "" -#: src/Module/Debug/Babel.php:309 +#: src/Module/Debug/Babel.php:311 msgid "HTML" msgstr "" -#: src/Module/Debug/Babel.php:311 +#: src/Module/Debug/Babel.php:313 msgid "Twitter Source / Tweet URL (requires API key)" msgstr "" @@ -9023,21 +9015,21 @@ msgstr "" msgid "Attributed To: %s
" msgstr "" -#: src/Module/Photo.php:130 +#: src/Module/Photo.php:123 msgid "The Photo is not available." msgstr "" -#: src/Module/Photo.php:155 +#: src/Module/Photo.php:148 #, php-format msgid "The Photo with id %s is not available." msgstr "" -#: src/Module/Photo.php:196 +#: src/Module/Photo.php:189 #, php-format msgid "Invalid external resource with url %s." msgstr "" -#: src/Module/Photo.php:198 +#: src/Module/Photo.php:191 #, php-format msgid "Invalid photo with id %s." msgstr ""