]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #6097 from nupplaphil/refactor_user_identities
authorHypolite Petovan <hypolite@mrpetovan.com>
Thu, 8 Nov 2018 11:54:48 +0000 (06:54 -0500)
committerGitHub <noreply@github.com>
Thu, 8 Nov 2018 11:54:48 +0000 (06:54 -0500)
Refactoring identities to Model\User::identities

13 files changed:
config/dbstructure.php
include/conversation.php
include/enotify.php
include/text.php
mod/item.php
src/Content/Text/BBCode.php
src/Model/Item.php
src/Object/Post.php
src/Protocol/ActivityPub/Processor.php
src/Protocol/ActivityPub/Receiver.php
src/Protocol/Email.php
src/Util/JsonLD.php
view/global.css

index 96f90fb8243b473381afd94ef4e7aff8dd812fee..99e3de9d067071779b19131f4b64618411399dac 100644 (file)
@@ -34,7 +34,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1289);
+       define('DB_UPDATE_VERSION', 1290);
 }
 
 return [
@@ -1368,7 +1368,10 @@ return [
                        "pid" => ["pid"],
                        "parameter" => ["parameter(64)"],
                        "priority_created_next_try" => ["priority", "created", "next_try"],
-                       "done_executed_next_try" => ["done", "executed", "next_try"]
+                       "done_priority_executed_next_try" => ["done", "priority", "executed", "next_try"],
+                       "done_executed_next_try" => ["done", "executed", "next_try"],
+                       "done_priority_next_try" => ["done", "priority", "next_try"],
+                       "done_next_try" => ["done", "next_try"]
                ]
        ]
 ];
index cd635521e51516545e43e937c4e294a252a4b3e6..e276fef139ee88dd0e94685b9b744afeecabe5c2 100644 (file)
@@ -638,7 +638,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
                                $lock = false;
                                $likebuttons = false;
 
-                               $body = prepare_body($item, true, $preview);
+                               $body = Item::prepareBody($item, true, $preview);
 
                                list($categories, $folders) = get_cats_and_terms($item);
 
@@ -689,7 +689,7 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
                                        'owner_name' => $owner_name_e,
                                        'owner_url' => $owner_url,
                                        'owner_photo' => System::removedBaseUrl(ProxyUtils::proxifyUrl($item['owner-avatar'], false, ProxyUtils::SIZE_THUMB)),
-                                       'plink' => get_plink($item),
+                                       'plink' => Item::getPlink($item),
                                        'edpost' => false,
                                        'isstarred' => $isstarred,
                                        'star' => $star,
index 339e31a3c810e01c14d3fc681e2462e687e42086..d6ca12327179404e772c743089012adbf5c54cdf 100644 (file)
@@ -157,7 +157,7 @@ function notification($params)
                        $item = Item::selectFirstForUser($params['uid'], Item::ITEM_FIELDLIST, ['id' => $parent_id]);
                }
 
-               $item_post_type = item_post_type($item);
+               $item_post_type = Item::postType($item);
                $itemlink = $item['plink'];
 
                // "a post"
index d2e3d0c9f9f12fcdc7d17423569faaa423a732c0..876cdbdb8a7d1ac30d5fddb70d8705c14893f704 100644 (file)
@@ -400,236 +400,6 @@ function redir_private_images($a, &$item)
        }
 }
 
-/**
- * Sets the "rendered-html" field of the provided item
- *
- * Body is preserved to avoid side-effects as we modify it just-in-time for spoilers and private image links
- *
- * @param array $item
- * @param bool  $update
- *
- * @todo Remove reference, simply return "rendered-html" and "rendered-hash"
- */
-function put_item_in_cache(&$item, $update = false)
-{
-       $body = $item["body"];
-
-       $rendered_hash = defaults($item, 'rendered-hash', '');
-       $rendered_html = defaults($item, 'rendered-html', '');
-
-       if ($rendered_hash == ''
-               || $rendered_html == ""
-               || $rendered_hash != hash("md5", $item["body"])
-               || Config::get("system", "ignore_cache")
-       ) {
-               $a = get_app();
-               redir_private_images($a, $item);
-
-               $item["rendered-html"] = prepare_text($item["body"]);
-               $item["rendered-hash"] = hash("md5", $item["body"]);
-
-               $hook_data = ['item' => $item, 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']];
-               Addon::callHooks('put_item_in_cache', $hook_data);
-               $item['rendered-html'] = $hook_data['rendered-html'];
-               $item['rendered-hash'] = $hook_data['rendered-hash'];
-               unset($hook_data);
-
-               // Force an update if the generated values differ from the existing ones
-               if ($rendered_hash != $item["rendered-hash"]) {
-                       $update = true;
-               }
-
-               // Only compare the HTML when we forcefully ignore the cache
-               if (Config::get("system", "ignore_cache") && ($rendered_html != $item["rendered-html"])) {
-                       $update = true;
-               }
-
-               if ($update && !empty($item["id"])) {
-                       Item::update(['rendered-html' => $item["rendered-html"], 'rendered-hash' => $item["rendered-hash"]],
-                                       ['id' => $item["id"]]);
-               }
-       }
-
-       $item["body"] = $body;
-}
-
-/**
- * @brief Given an item array, convert the body element from bbcode to html and add smilie icons.
- * If attach is true, also add icons for item attachments.
- *
- * @param array   $item
- * @param boolean $attach
- * @param boolean $is_preview
- * @return string item body html
- * @hook prepare_body_init item array before any work
- * @hook prepare_body_content_filter ('item'=>item array, 'filter_reasons'=>string array) before first bbcode to html
- * @hook prepare_body ('item'=>item array, 'html'=>body string, 'is_preview'=>boolean, 'filter_reasons'=>string array) after first bbcode to html
- * @hook prepare_body_final ('item'=>item array, 'html'=>body string) after attach icons and blockquote special case handling (spoiler, author)
- */
-function prepare_body(array &$item, $attach = false, $is_preview = false)
-{
-       $a = get_app();
-       Addon::callHooks('prepare_body_init', $item);
-
-       // In order to provide theme developers more possibilities, event items
-       // are treated differently.
-       if ($item['object-type'] === ACTIVITY_OBJ_EVENT && isset($item['event-id'])) {
-               $ev = Event::getItemHTML($item);
-               return $ev;
-       }
-
-       $tags = \Friendica\Model\Term::populateTagsFromItem($item);
-
-       $item['tags'] = $tags['tags'];
-       $item['hashtags'] = $tags['hashtags'];
-       $item['mentions'] = $tags['mentions'];
-
-       // Compile eventual content filter reasons
-       $filter_reasons = [];
-       if (!$is_preview && public_contact() != $item['author-id']) {
-               if (!empty($item['content-warning']) && (!local_user() || !PConfig::get(local_user(), 'system', 'disable_cw', false))) {
-                       $filter_reasons[] = L10n::t('Content warning: %s', $item['content-warning']);
-               }
-
-               $hook_data = [
-                       'item' => $item,
-                       'filter_reasons' => $filter_reasons
-               ];
-               Addon::callHooks('prepare_body_content_filter', $hook_data);
-               $filter_reasons = $hook_data['filter_reasons'];
-               unset($hook_data);
-       }
-
-       // Update the cached values if there is no "zrl=..." on the links.
-       $update = (!local_user() && !remote_user() && ($item["uid"] == 0));
-
-       // Or update it if the current viewer is the intented viewer.
-       if (($item["uid"] == local_user()) && ($item["uid"] != 0)) {
-               $update = true;
-       }
-
-       put_item_in_cache($item, $update);
-       $s = $item["rendered-html"];
-
-       $hook_data = [
-               'item' => $item,
-               'html' => $s,
-               'preview' => $is_preview,
-               'filter_reasons' => $filter_reasons
-       ];
-       Addon::callHooks('prepare_body', $hook_data);
-       $s = $hook_data['html'];
-       unset($hook_data);
-
-       if (!$attach) {
-               // Replace the blockquotes with quotes that are used in mails.
-               $mailquote = '<blockquote type="cite" class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">';
-               $s = str_replace(['<blockquote>', '<blockquote class="spoiler">', '<blockquote class="author">'], [$mailquote, $mailquote, $mailquote], $s);
-               return $s;
-       }
-
-       $as = '';
-       $vhead = false;
-       $matches = [];
-       preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\"(?: title=\"(.*?)\")?|', $item['attach'], $matches, PREG_SET_ORDER);
-       foreach ($matches as $mtch) {
-               $mime = $mtch[3];
-
-               $the_url = Contact::magicLinkById($item['author-id'], $mtch[1]);
-
-               if (strpos($mime, 'video') !== false) {
-                       if (!$vhead) {
-                               $vhead = true;
-                               $a->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('videos_head.tpl'), [
-                                       '$baseurl' => System::baseUrl(),
-                               ]);
-                       }
-
-                       $url_parts = explode('/', $the_url);
-                       $id = end($url_parts);
-                       $as .= Renderer::replaceMacros(Renderer::getMarkupTemplate('video_top.tpl'), [
-                               '$video' => [
-                                       'id'     => $id,
-                                       'title'  => L10n::t('View Video'),
-                                       'src'    => $the_url,
-                                       'mime'   => $mime,
-                               ],
-                       ]);
-               }
-
-               $filetype = strtolower(substr($mime, 0, strpos($mime, '/')));
-               if ($filetype) {
-                       $filesubtype = strtolower(substr($mime, strpos($mime, '/') + 1));
-                       $filesubtype = str_replace('.', '-', $filesubtype);
-               } else {
-                       $filetype = 'unkn';
-                       $filesubtype = 'unkn';
-               }
-
-               $title = escape_tags(trim(!empty($mtch[4]) ? $mtch[4] : $mtch[1]));
-               $title .= ' ' . $mtch[2] . ' ' . L10n::t('bytes');
-
-               $icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
-               $as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" >' . $icon . '</a>';
-       }
-
-       if ($as != '') {
-               $s .= '<div class="body-attach">'.$as.'<div class="clear"></div></div>';
-       }
-
-       // Map.
-       if (strpos($s, '<div class="map">') !== false && x($item, 'coord')) {
-               $x = Map::byCoordinates(trim($item['coord']));
-               if ($x) {
-                       $s = preg_replace('/\<div class\=\"map\"\>/', '$0' . $x, $s);
-               }
-       }
-
-
-       // Look for spoiler.
-       $spoilersearch = '<blockquote class="spoiler">';
-
-       // Remove line breaks before the spoiler.
-       while ((strpos($s, "\n" . $spoilersearch) !== false)) {
-               $s = str_replace("\n" . $spoilersearch, $spoilersearch, $s);
-       }
-       while ((strpos($s, "<br />" . $spoilersearch) !== false)) {
-               $s = str_replace("<br />" . $spoilersearch, $spoilersearch, $s);
-       }
-
-       while ((strpos($s, $spoilersearch) !== false)) {
-               $pos = strpos($s, $spoilersearch);
-               $rnd = random_string(8);
-               $spoilerreplace = '<br /> <span id="spoiler-wrap-' . $rnd . '" class="spoiler-wrap fakelink" onclick="openClose(\'spoiler-' . $rnd . '\');">' . L10n::t('Click to open/close') . '</span>'.
-                                       '<blockquote class="spoiler" id="spoiler-' . $rnd . '" style="display: none;">';
-               $s = substr($s, 0, $pos) . $spoilerreplace . substr($s, $pos + strlen($spoilersearch));
-       }
-
-       // Look for quote with author.
-       $authorsearch = '<blockquote class="author">';
-
-       while ((strpos($s, $authorsearch) !== false)) {
-               $pos = strpos($s, $authorsearch);
-               $rnd = random_string(8);
-               $authorreplace = '<br /> <span id="author-wrap-' . $rnd . '" class="author-wrap fakelink" onclick="openClose(\'author-' . $rnd . '\');">' . L10n::t('Click to open/close') . '</span>'.
-                                       '<blockquote class="author" id="author-' . $rnd . '" style="display: block;">';
-               $s = substr($s, 0, $pos) . $authorreplace . substr($s, $pos + strlen($authorsearch));
-       }
-
-       // Replace friendica image url size with theme preference.
-       if (x($a->theme_info, 'item_image_size')){
-               $ps = $a->theme_info['item_image_size'];
-               $s = preg_replace('|(<img[^>]+src="[^"]+/photo/[0-9a-f]+)-[0-9]|', "$1-" . $ps, $s);
-       }
-
-       $s = HTML::applyContentFilter($s, $filter_reasons);
-
-       $hook_data = ['item' => $item, 'html' => $s];
-       Addon::callHooks('prepare_body_final', $hook_data);
-
-       return $hook_data['html'];
-}
-
 /**
  * @brief Given a text string, convert from bbcode to html and add smilie icons.
  *
@@ -723,42 +493,6 @@ function get_cats_and_terms($item)
        return [$categories, $folders];
 }
 
-
-/**
- * get private link for item
- * @param array $item
- * @return boolean|array False if item has not plink, otherwise array('href'=>plink url, 'title'=>translated title)
- */
-function get_plink($item) {
-       $a = get_app();
-
-       if ($a->user['nickname'] != "") {
-               $ret = [
-                               //'href' => "display/" . $a->user['nickname'] . "/" . $item['id'],
-                               'href' => "display/" . $item['guid'],
-                               'orig' => "display/" . $item['guid'],
-                               'title' => L10n::t('View on separate page'),
-                               'orig_title' => L10n::t('view on separate page'),
-                       ];
-
-               if (x($item, 'plink')) {
-                       $ret["href"] = $a->removeBaseURL($item['plink']);
-                       $ret["title"] = L10n::t('link to source');
-               }
-
-       } elseif (x($item, 'plink') && ($item['private'] != 1)) {
-               $ret = [
-                               'href' => $item['plink'],
-                               'orig' => $item['plink'],
-                               'title' => L10n::t('link to source'),
-                       ];
-       } else {
-               $ret = [];
-       }
-
-       return $ret;
-}
-
 /**
  * return number of bytes in size (K, M, G)
  * @param string $size_str
@@ -836,26 +570,6 @@ function bb_translate_video($s) {
        return $s;
 }
 
-/**
- * get translated item type
- *
- * @param array $itme
- * @return string
- */
-function item_post_type($item) {
-       if (!empty($item['event-id'])) {
-               return L10n::t('event');
-       } elseif (!empty($item['resource-id'])) {
-               return L10n::t('photo');
-       } elseif (!empty($item['verb']) && $item['verb'] !== ACTIVITY_POST) {
-               return L10n::t('activity');
-       } elseif ($item['id'] != $item['parent']) {
-               return L10n::t('comment');
-       }
-
-       return L10n::t('post');
-}
-
 function normalise_openid($s) {
        return trim(str_replace(['http://', 'https://'], ['', ''], $s), '/');
 }
index 739e09ab0fecc03c39c74c0a3d1cee9c250f4e7b..c86ed5e2787678509e366a0b729e7dd022e45b17 100644 (file)
@@ -697,11 +697,10 @@ function item_post(App $a) {
                killme();
        }
 
-       if ($orig_post) {
-
+       if ($orig_post) {
                // Fill the cache field
                // This could be done in Item::update as well - but we have to check for the existance of some fields.
-               put_item_in_cache($datarray);
+               Item::putInCache($datarray);
 
                $fields = [
                        'title' => $datarray['title'],
@@ -817,7 +816,7 @@ function item_post(App $a) {
                                        $subject = Email::encodeHeader('[Friendica]' . ' ' . L10n::t('%s posted an update.', $a->user['username']), 'UTF-8');
                                }
                                $link = '<a href="' . System::baseUrl() . '/profile/' . $a->user['nickname'] . '"><img src="' . $author['thumb'] . '" alt="' . $a->user['username'] . '" /></a><br /><br />';
-                               $html    = prepare_body($datarray);
+                               $html    = Item::prepareBody($datarray);
                                $message = '<html><body>' . $link . $html . $disclaimer . '</body></html>';
                                $params =  [
                                        'fromName' => $a->user['username'],
index 3592059d0ca76770ac7698fb7ac9bc449559b30e..f37400f836ac8e9c46fd817c21312dce432dee3e 100644 (file)
@@ -1363,7 +1363,7 @@ class BBCode extends BaseObject
                $text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $text);
 
                // leave open the posibility of [map=something]
-               // this is replaced in prepare_body() which has knowledge of the item location
+               // this is replaced in Item::prepareBody() which has knowledge of the item location
 
                if (strpos($text, '[/map]') !== false) {
                        $text = preg_replace_callback(
@@ -1474,7 +1474,7 @@ class BBCode extends BaseObject
 
                $text = str_replace('[hr]', '<hr />', $text);
 
-               // This is actually executed in prepare_body()
+               // This is actually executed in Item::prepareBody()
 
                $text = str_replace('[nosmile]', '', $text);
 
index 8e0a397e24564bf819aba22992a5bb7a7d8eca41..1eb96609f2ace041f2f9ade9af459bc340753fad 100644 (file)
@@ -8,23 +8,29 @@ namespace Friendica\Model;
 
 use Friendica\BaseObject;
 use Friendica\Content\Text\BBCode;
+use Friendica\Content\Text\HTML;
 use Friendica\Core\Addon;
 use Friendica\Core\Config;
 use Friendica\Core\Lock;
 use Friendica\Core\Logger;
+use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
 use Friendica\Core\Protocol;
+use Friendica\Core\Renderer;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Contact;
+use Friendica\Model\Event;
 use Friendica\Model\FileTag;
 use Friendica\Model\PermissionSet;
+use Friendica\Model\Term;
 use Friendica\Model\ItemURI;
 use Friendica\Object\Image;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
 use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Map;
 use Friendica\Util\XML;
 use Friendica\Util\Security;
 use Text_LanguageDetect;
@@ -1607,7 +1613,7 @@ class Item extends BaseObject
                $item["deleted"] = $parent_deleted;
 
                // Fill the cache field
-               put_item_in_cache($item);
+               self::putInCache($item);
 
                if ($notify) {
                        $item['edit'] = false;
@@ -3247,4 +3253,295 @@ class Item extends BaseObject
 
                return $sql;
        }
+
+       /**
+        * get translated item type
+        *
+        * @param array $itme
+        * @return string
+        */
+       public static function postType($item)
+       {
+               if (!empty($item['event-id'])) {
+                       return L10n::t('event');
+               } elseif (!empty($item['resource-id'])) {
+                       return L10n::t('photo');
+               } elseif (!empty($item['verb']) && $item['verb'] !== ACTIVITY_POST) {
+                       return L10n::t('activity');
+               } elseif ($item['id'] != $item['parent']) {
+                       return L10n::t('comment');
+               }
+
+               return L10n::t('post');
+       }
+
+       /**
+        * Sets the "rendered-html" field of the provided item
+        *
+        * Body is preserved to avoid side-effects as we modify it just-in-time for spoilers and private image links
+        *
+        * @param array $item
+        * @param bool  $update
+        *
+        * @todo Remove reference, simply return "rendered-html" and "rendered-hash"
+        */
+       public static function putInCache(&$item, $update = false)
+       {
+               $body = $item["body"];
+
+               $rendered_hash = defaults($item, 'rendered-hash', '');
+               $rendered_html = defaults($item, 'rendered-html', '');
+
+               if ($rendered_hash == ''
+                       || $rendered_html == ""
+                       || $rendered_hash != hash("md5", $item["body"])
+                       || Config::get("system", "ignore_cache")
+               ) {
+                       $a = self::getApp();
+                       redir_private_images($a, $item);
+
+                       $item["rendered-html"] = prepare_text($item["body"]);
+                       $item["rendered-hash"] = hash("md5", $item["body"]);
+
+                       $hook_data = ['item' => $item, 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']];
+                       Addon::callHooks('put_item_in_cache', $hook_data);
+                       $item['rendered-html'] = $hook_data['rendered-html'];
+                       $item['rendered-hash'] = $hook_data['rendered-hash'];
+                       unset($hook_data);
+
+                       // Force an update if the generated values differ from the existing ones
+                       if ($rendered_hash != $item["rendered-hash"]) {
+                               $update = true;
+                       }
+
+                       // Only compare the HTML when we forcefully ignore the cache
+                       if (Config::get("system", "ignore_cache") && ($rendered_html != $item["rendered-html"])) {
+                               $update = true;
+                       }
+
+                       if ($update && !empty($item["id"])) {
+                               self::update(
+                                       [
+                                               'rendered-html' => $item["rendered-html"],
+                                               'rendered-hash' => $item["rendered-hash"]
+                                       ],
+                                       ['id' => $item["id"]]
+                               );
+                       }
+               }
+
+               $item["body"] = $body;
+       }
+
+       /**
+        * @brief Given an item array, convert the body element from bbcode to html and add smilie icons.
+        * If attach is true, also add icons for item attachments.
+        *
+        * @param array   $item
+        * @param boolean $attach
+        * @param boolean $is_preview
+        * @return string item body html
+        * @hook prepare_body_init item array before any work
+        * @hook prepare_body_content_filter ('item'=>item array, 'filter_reasons'=>string array) before first bbcode to html
+        * @hook prepare_body ('item'=>item array, 'html'=>body string, 'is_preview'=>boolean, 'filter_reasons'=>string array) after first bbcode to html
+        * @hook prepare_body_final ('item'=>item array, 'html'=>body string) after attach icons and blockquote special case handling (spoiler, author)
+        */
+       public static function prepareBody(array &$item, $attach = false, $is_preview = false)
+       {
+               $a = self::getApp();
+               Addon::callHooks('prepare_body_init', $item);
+
+               // In order to provide theme developers more possibilities, event items
+               // are treated differently.
+               if ($item['object-type'] === ACTIVITY_OBJ_EVENT && isset($item['event-id'])) {
+                       $ev = Event::getItemHTML($item);
+                       return $ev;
+               }
+
+               $tags = Term::populateTagsFromItem($item);
+
+               $item['tags'] = $tags['tags'];
+               $item['hashtags'] = $tags['hashtags'];
+               $item['mentions'] = $tags['mentions'];
+
+               // Compile eventual content filter reasons
+               $filter_reasons = [];
+               if (!$is_preview && public_contact() != $item['author-id']) {
+                       if (!empty($item['content-warning']) && (!local_user() || !PConfig::get(local_user(), 'system', 'disable_cw', false))) {
+                               $filter_reasons[] = L10n::t('Content warning: %s', $item['content-warning']);
+                       }
+
+                       $hook_data = [
+                               'item' => $item,
+                               'filter_reasons' => $filter_reasons
+                       ];
+                       Addon::callHooks('prepare_body_content_filter', $hook_data);
+                       $filter_reasons = $hook_data['filter_reasons'];
+                       unset($hook_data);
+               }
+
+               // Update the cached values if there is no "zrl=..." on the links.
+               $update = (!local_user() && !remote_user() && ($item["uid"] == 0));
+
+               // Or update it if the current viewer is the intented viewer.
+               if (($item["uid"] == local_user()) && ($item["uid"] != 0)) {
+                       $update = true;
+               }
+
+               self::putInCache($item, $update);
+               $s = $item["rendered-html"];
+
+               $hook_data = [
+                       'item' => $item,
+                       'html' => $s,
+                       'preview' => $is_preview,
+                       'filter_reasons' => $filter_reasons
+               ];
+               Addon::callHooks('prepare_body', $hook_data);
+               $s = $hook_data['html'];
+               unset($hook_data);
+
+               if (!$attach) {
+                       // Replace the blockquotes with quotes that are used in mails.
+                       $mailquote = '<blockquote type="cite" class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">';
+                       $s = str_replace(['<blockquote>', '<blockquote class="spoiler">', '<blockquote class="author">'], [$mailquote, $mailquote, $mailquote], $s);
+                       return $s;
+               }
+
+               $as = '';
+               $vhead = false;
+               $matches = [];
+               preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\"(?: title=\"(.*?)\")?|', $item['attach'], $matches, PREG_SET_ORDER);
+               foreach ($matches as $mtch) {
+                       $mime = $mtch[3];
+
+                       $the_url = Contact::magicLinkById($item['author-id'], $mtch[1]);
+
+                       if (strpos($mime, 'video') !== false) {
+                               if (!$vhead) {
+                                       $vhead = true;
+                                       $a->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('videos_head.tpl'), [
+                                               '$baseurl' => System::baseUrl(),
+                                       ]);
+                               }
+
+                               $url_parts = explode('/', $the_url);
+                               $id = end($url_parts);
+                               $as .= Renderer::replaceMacros(Renderer::getMarkupTemplate('video_top.tpl'), [
+                                       '$video' => [
+                                               'id'     => $id,
+                                               'title'  => L10n::t('View Video'),
+                                               'src'    => $the_url,
+                                               'mime'   => $mime,
+                                       ],
+                               ]);
+                       }
+
+                       $filetype = strtolower(substr($mime, 0, strpos($mime, '/')));
+                       if ($filetype) {
+                               $filesubtype = strtolower(substr($mime, strpos($mime, '/') + 1));
+                               $filesubtype = str_replace('.', '-', $filesubtype);
+                       } else {
+                               $filetype = 'unkn';
+                               $filesubtype = 'unkn';
+                       }
+
+                       $title = escape_tags(trim(!empty($mtch[4]) ? $mtch[4] : $mtch[1]));
+                       $title .= ' ' . $mtch[2] . ' ' . L10n::t('bytes');
+
+                       $icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
+                       $as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" >' . $icon . '</a>';
+               }
+
+               if ($as != '') {
+                       $s .= '<div class="body-attach">'.$as.'<div class="clear"></div></div>';
+               }
+
+               // Map.
+               if (strpos($s, '<div class="map">') !== false && x($item, 'coord')) {
+                       $x = Map::byCoordinates(trim($item['coord']));
+                       if ($x) {
+                               $s = preg_replace('/\<div class\=\"map\"\>/', '$0' . $x, $s);
+                       }
+               }
+
+
+               // Look for spoiler.
+               $spoilersearch = '<blockquote class="spoiler">';
+
+               // Remove line breaks before the spoiler.
+               while ((strpos($s, "\n" . $spoilersearch) !== false)) {
+                       $s = str_replace("\n" . $spoilersearch, $spoilersearch, $s);
+               }
+               while ((strpos($s, "<br />" . $spoilersearch) !== false)) {
+                       $s = str_replace("<br />" . $spoilersearch, $spoilersearch, $s);
+               }
+
+               while ((strpos($s, $spoilersearch) !== false)) {
+                       $pos = strpos($s, $spoilersearch);
+                       $rnd = random_string(8);
+                       $spoilerreplace = '<br /> <span id="spoiler-wrap-' . $rnd . '" class="spoiler-wrap fakelink" onclick="openClose(\'spoiler-' . $rnd . '\');">' . L10n::t('Click to open/close') . '</span>'.
+                                               '<blockquote class="spoiler" id="spoiler-' . $rnd . '" style="display: none;">';
+                       $s = substr($s, 0, $pos) . $spoilerreplace . substr($s, $pos + strlen($spoilersearch));
+               }
+
+               // Look for quote with author.
+               $authorsearch = '<blockquote class="author">';
+
+               while ((strpos($s, $authorsearch) !== false)) {
+                       $pos = strpos($s, $authorsearch);
+                       $rnd = random_string(8);
+                       $authorreplace = '<br /> <span id="author-wrap-' . $rnd . '" class="author-wrap fakelink" onclick="openClose(\'author-' . $rnd . '\');">' . L10n::t('Click to open/close') . '</span>'.
+                                               '<blockquote class="author" id="author-' . $rnd . '" style="display: block;">';
+                       $s = substr($s, 0, $pos) . $authorreplace . substr($s, $pos + strlen($authorsearch));
+               }
+
+               // Replace friendica image url size with theme preference.
+               if (!empty($a->theme_info['item_image_size'])) {
+                       $ps = $a->theme_info['item_image_size'];
+                       $s = preg_replace('|(<img[^>]+src="[^"]+/photo/[0-9a-f]+)-[0-9]|', "$1-" . $ps, $s);
+               }
+
+               $s = HTML::applyContentFilter($s, $filter_reasons);
+
+               $hook_data = ['item' => $item, 'html' => $s];
+               Addon::callHooks('prepare_body_final', $hook_data);
+
+               return $hook_data['html'];
+       }
+
+       /**
+        * get private link for item
+        * @param array $item
+        * @return boolean|array False if item has not plink, otherwise array('href'=>plink url, 'title'=>translated title)
+        */
+       public static function getPlink($item)
+       {
+               $a = self::getApp();
+
+               if ($a->user['nickname'] != "") {
+                       $ret = [
+                               'href' => "display/" . $item['guid'],
+                               'orig' => "display/" . $item['guid'],
+                               'title' => L10n::t('View on separate page'),
+                               'orig_title' => L10n::t('view on separate page'),
+                       ];
+
+                       if (!empty($item['plink'])) {
+                               $ret["href"] = $a->removeBaseURL($item['plink']);
+                               $ret["title"] = L10n::t('link to source');
+                       }
+
+               } elseif (!empty($item['plink']) && ($item['private'] != 1)) {
+                       $ret = [
+                               'href' => $item['plink'],
+                               'orig' => $item['plink'],
+                               'title' => L10n::t('link to source'),
+                       ];
+               } else {
+                       $ret = [];
+               }
+
+               return $ret;
+       }
 }
index 644d53e25d8207f8f9d2d16180ba5ec9903ac98e..e0e3beadb3ec53200bfe9549395f987773d1d9ef 100644 (file)
@@ -315,7 +315,7 @@ class Post extends BaseObject
 
                localize_item($item);
 
-               $body = prepare_body($item, true);
+               $body = Item::prepareBody($item, true);
 
                list($categories, $folders) = get_cats_and_terms($item);
 
@@ -392,7 +392,7 @@ class Post extends BaseObject
                        'owner_url'       => $this->getOwnerUrl(),
                        'owner_photo'     => $a->removeBaseURL(ProxyUtils::proxifyUrl($item['owner-avatar'], false, ProxyUtils::SIZE_THUMB)),
                        'owner_name'      => htmlentities($owner_name_e),
-                       'plink'           => get_plink($item),
+                       'plink'           => Item::getPlink($item),
                        'edpost'          => Feature::isEnabled($conv->getProfileOwner(), 'edit_posts') ? $edpost : '',
                        'isstarred'       => $isstarred,
                        'star'            => Feature::isEnabled($conv->getProfileOwner(), 'star_posts') ? $star : '',
index 1e5001010855ae68b8b8beaf25b75b6ed4903398..5dadc029f924c41869ee34185cac5410f365a856 100644 (file)
@@ -39,6 +39,23 @@ class Processor
                return $body;
        }
 
+       /**
+        * Replaces emojis in the body
+        *
+        * @param array $emojis
+        * @param string $body
+        *
+        * @return string with replaced emojis
+        */
+       public static function replaceEmojis($emojis, $body)
+       {
+               foreach ($emojis as $emoji) {
+                       $replace = '[class=emoji mastodon][img=' . $emoji['href'] . ']' . $emoji['name'] . '[/img][/class]';
+                       $body = str_replace($emoji['name'], $replace, $body);
+               }
+               return $body;
+       }
+
        /**
         * Constructs a string with tags for a given tag array
         *
@@ -115,7 +132,8 @@ class Processor
                $item['edited'] = $activity['updated'];
                $item['title'] = HTML::toBBCode($activity['name']);
                $item['content-warning'] = HTML::toBBCode($activity['summary']);
-               $item['body'] = self::convertMentions(HTML::toBBCode($activity['content']));
+               $content = self::replaceEmojis($activity['emojis'], HTML::toBBCode($activity['content']));
+               $item['body'] = self::convertMentions($content);
                $item['tag'] = self::constructTagList($activity['tags'], $activity['sensitive']);
 
                Item::update($item, ['uri' => $activity['id']]);
@@ -250,7 +268,8 @@ class Processor
                $item['guid'] = $activity['diaspora:guid'];
                $item['title'] = HTML::toBBCode($activity['name']);
                $item['content-warning'] = HTML::toBBCode($activity['summary']);
-               $item['body'] = self::convertMentions(HTML::toBBCode($activity['content']));
+               $content = self::replaceEmojis($activity['emojis'], HTML::toBBCode($activity['content']));
+               $item['body'] = self::convertMentions($content);
 
                if (($activity['object_type'] == 'as:Video') && !empty($activity['alternate-url'])) {
                        $item['body'] .= "\n[video]" . $activity['alternate-url'] . '[/video]';
index 2cc165b233d7e230a44f7479b59a5f11633e8fc2..c958b9d6c3c46de6bf99ee0f3069cd1eee6c2c74 100644 (file)
@@ -727,13 +727,48 @@ class Receiver
                                continue;
                        }
 
-                       $taglist[] = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type')),
+                       $element = ['type' => str_replace('as:', '', JsonLD::fetchElement($tag, '@type')),
                                'href' => JsonLD::fetchElement($tag, 'as:href'),
                                'name' => JsonLD::fetchElement($tag, 'as:name')];
+
+                       if (empty($element['type'])) {
+                               continue;
+                       }
+
+                       $taglist[] = $element;
                }
                return $taglist;
        }
 
+       /**
+        * Convert emojis from JSON-LD format into a simplified format
+        *
+        * @param array $tags Tags in JSON-LD format
+        *
+        * @return array with emojis in a simplified format
+        */
+       private static function processEmojis($emojis)
+       {
+               $emojilist = [];
+
+               if (empty($emojis)) {
+                       return [];
+               }
+
+               foreach ($emojis as $emoji) {
+                       if (empty($emoji) || (JsonLD::fetchElement($emoji, '@type') != 'toot:Emoji') || empty($emoji['as:icon'])) {
+                               continue;
+                       }
+
+                       $url = JsonLD::fetchElement($emoji['as:icon'], 'as:url');
+                       $element = ['name' => JsonLD::fetchElement($emoji, 'as:name'),
+                               'href' => $url];
+
+                       $emojilist[] = $element;
+               }
+               return $emojilist;
+       }
+
        /**
         * Convert attachments from JSON-LD format into a simplified format
         *
@@ -821,6 +856,7 @@ class Receiver
                $object_data['longitude'] = JsonLD::fetchElement($object_data, 'longitude', '@value');
                $object_data['attachments'] = self::processAttachments(JsonLD::fetchElementArray($object, 'as:attachment'));
                $object_data['tags'] = self::processTags(JsonLD::fetchElementArray($object, 'as:tag'));
+               $object_data['emojis'] = self::processEmojis(JsonLD::fetchElementArray($object, 'as:tag', 'toot:Emoji'));
                $object_data['generator'] = JsonLD::fetchElement($object, 'as:generator', 'as:name', '@type', 'as:Application');
                $object_data['alternate-url'] = JsonLD::fetchElement($object, 'as:url');
 
index bb70972b03ced7d9f11fdbe1d66131ab94b08b95..ba8c311901a9bc241db400ee96f45dd0253469ba 100644 (file)
@@ -7,6 +7,7 @@ namespace Friendica\Protocol;
 use Friendica\Core\Logger;
 use Friendica\Content\Text\HTML;
 use Friendica\Core\Protocol;
+use Friendica\Model\Item;
 
 /**
  * @brief Email class
@@ -331,7 +332,7 @@ class Email
 
                $part = uniqid("", true);
 
-               $html    = prepare_body($item);
+               $html    = Item::prepareBody($item);
 
                $headers .= "Mime-Version: 1.0\n";
                $headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n";
index bed7a67d60a01eeccf58bc6a312f6f363541f4b6..78d81816e25b1747c0f749e9488470bdcdfb6727 100644 (file)
@@ -90,7 +90,8 @@ class JsonLD
                        'dfrn' => (object)['@id' => 'http://purl.org/macgirvin/dfrn/1.0/', '@type' => '@id'],
                        'diaspora' => (object)['@id' => 'https://diasporafoundation.org/ns/', '@type' => '@id'],
                        'ostatus' => (object)['@id' => 'http://ostatus.org#', '@type' => '@id'],
-                       'dc' => (object)['@id' => 'http://purl.org/dc/terms/', '@type' => '@id']];
+                       'dc' => (object)['@id' => 'http://purl.org/dc/terms/', '@type' => '@id'],
+                       'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id']];
 
                $jsonobj = json_decode(json_encode($json, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
 
index b46862d5aacc140fb22b299e6f5fb81eab9da01c..48755b89dcbeee586fc8a14caf8ff0ea05115d19 100644 (file)
@@ -602,3 +602,8 @@ img.invalid-src:after { vertical-align: top;}
 #register-explicid-content {
   font-weight: bold;
 }
+
+span.emoji.mastodon img {
+  height: 1.2em;
+  vertical-align: middle;
+}