]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #7856 from casperrutten/develop
authorHypolite Petovan <hypolite@mrpetovan.com>
Fri, 22 Nov 2019 16:54:36 +0000 (11:54 -0500)
committerGitHub <noreply@github.com>
Fri, 22 Nov 2019 16:54:36 +0000 (11:54 -0500)
Update to version 1.9.1

17 files changed:
doc/Addons.md
doc/de/Addons.md
include/api.php
include/conversation.php
mod/settings.php
src/Content/Text/BBCode.php
src/Model/GServer.php
src/Model/Item.php
src/Protocol/ActivityPub/Transmitter.php
src/Protocol/Diaspora.php
src/Protocol/Email.php
src/Protocol/Feed.php
src/Util/ParseUrl.php
src/Worker/Notifier.php
src/Worker/OnePoll.php
view/templates/settings/connectors.tpl
view/theme/frio/templates/settings/connectors.tpl

index 69b591a820f724f8a1936f0fafc0d124244e8140..fb9956089dbf4d2ca371d7f61ce588675e8a8c9a 100644 (file)
@@ -777,6 +777,11 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
     Hook::callAll('atom_feed_end', $atom);
     Hook::callAll('atom_feed_end', $atom);
 
+### src/Protocol/Email.php
+
+    Hook::callAll('email_getmessage', $message);
+    Hook::callAll('email_getmessage_end', $ret);
+
 ### view/js/main.js
 
     document.dispatchEvent(new Event('postprocess_liveupdate'));
index 755db95d018ce00634bfcd83e62b1e48b7d314f0..b5dd07cca2305965806ee1b72faaf62108459042 100644 (file)
@@ -495,3 +495,8 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
 
     Hook::callAll('atom_feed_end', $atom);
     Hook::callAll('atom_feed_end', $atom);
+
+### src/Protocol/Email.php
+
+    Hook::callAll('email_getmessage', $message);
+    Hook::callAll('email_getmessage_end', $ret);
index 8325e39b71442f6518054ac1293ea3657ae666ab..22fe64097bbafa8640f75df8f5c01d4661fc006e 100644 (file)
@@ -959,7 +959,7 @@ function api_account_verify_credentials($type)
        // - Adding last status
        if (!$skip_status) {
                $item = api_get_last_status($user_info['pid'], $user_info['uid']);
-               if ($item) {
+               if (!empty($item)) {
                        $user_info['status'] = api_format_item($item, $type);
                }
        }
@@ -1318,7 +1318,7 @@ function api_status_show($type, $item_id)
        $status_info = [];
 
        $item = api_get_item(['id' => $item_id]);
-       if ($item) {
+       if (!empty($item)) {
                $status_info = api_format_item($item, $type);
        }
 
@@ -1382,7 +1382,7 @@ function api_users_show($type)
        $user_info = api_get_user($a);
 
        $item = api_get_last_status($user_info['pid'], $user_info['uid']);
-       if ($item) {
+       if (!empty($item)) {
                $user_info['status'] = api_format_item($item, $type);
        }
 
index b7f8d91fc40cd37193851788f0cb0383e7949eaf..c1f89ea9b0960fff69ef236632063a413fa723c2 100644 (file)
@@ -402,7 +402,7 @@ function visible_activity($item) {
        /** @var Activity $activity */
        $activity = BaseObject::getClass(Activity::class);
 
-       if ($activity->isHidden($item['verb'])) {
+       if (empty($item['verb']) || $activity->isHidden($item['verb'])) {
                return false;
        }
 
@@ -1034,7 +1034,7 @@ function builtin_activity_puller($item, &$conv_responses) {
                /** @var Activity $activity */
                $activity = BaseObject::getClass(Activity::class);
 
-               if ($activity->match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
+               if (!empty($item['verb']) && $activity->match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
                        $author = ['uid' => 0, 'id' => $item['author-id'],
                                'network' => $item['author-network'], 'url' => $item['author-link']];
                        $url = Contact::magicLinkByContact($author);
index 5ae4086b61741e48ce7145b555a06f073f2569de..fcc2cad36950f9b0a196be293489e047653f49ec 100644 (file)
@@ -239,6 +239,7 @@ function settings_post(App $a)
                        PConfig::set(local_user(), 'system', 'accept_only_sharer', intval($_POST['accept_only_sharer']));
                        PConfig::set(local_user(), 'system', 'disable_cw', intval($_POST['disable_cw']));
                        PConfig::set(local_user(), 'system', 'no_intelligent_shortening', intval($_POST['no_intelligent_shortening']));
+                       PConfig::set(local_user(), 'system', 'attach_link_title', intval($_POST['attach_link_title']));
                        PConfig::set(local_user(), 'system', 'ostatus_autofriend', intval($_POST['snautofollow']));
                        PConfig::set(local_user(), 'ostatus', 'default_group', $_POST['group-selection']);
                        PConfig::set(local_user(), 'ostatus', 'legacy_contact', $_POST['legacy_contact']);
@@ -782,6 +783,7 @@ function settings_content(App $a)
                $accept_only_sharer        = intval(PConfig::get(local_user(), 'system', 'accept_only_sharer'));
                $disable_cw                = intval(PConfig::get(local_user(), 'system', 'disable_cw'));
                $no_intelligent_shortening = intval(PConfig::get(local_user(), 'system', 'no_intelligent_shortening'));
+               $attach_link_title         = intval(PConfig::get(local_user(), 'system', 'attach_link_title'));
                $ostatus_autofriend        = intval(PConfig::get(local_user(), 'system', 'ostatus_autofriend'));
                $default_group             = PConfig::get(local_user(), 'ostatus', 'default_group');
                $legacy_contact            = PConfig::get(local_user(), 'ostatus', 'legacy_contact');
@@ -841,6 +843,7 @@ function settings_content(App $a)
                        '$accept_only_sharer' => ['accept_only_sharer', L10n::t('Accept only top level posts by contacts you follow'), $accept_only_sharer, L10n::t('The system does an auto completion of threads when a comment arrives. This has got the side effect that you can receive posts that had been started by a non-follower but had been commented by someone you follow. This setting deactivates this behaviour. When activated, you strictly only will receive posts from people you really do follow.')],
                        '$disable_cw' => ['disable_cw', L10n::t('Disable Content Warning'), $disable_cw, L10n::t('Users on networks like Mastodon or Pleroma are able to set a content warning field which collapse their post by default. This disables the automatic collapsing and sets the content warning as the post title. Doesn\'t affect any other content filtering you eventually set up.')],
                        '$no_intelligent_shortening' => ['no_intelligent_shortening', L10n::t('Disable intelligent shortening'), $no_intelligent_shortening, L10n::t('Normally the system tries to find the best link to add to shortened posts. If this option is enabled then every shortened post will always point to the original friendica post.')],
+                       '$attach_link_title' => ['attach_link_title', L10n::t('Attach the link title'), $attach_link_title, L10n::t('When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.')],
                        '$ostatus_autofriend' => ['snautofollow', L10n::t("Automatically follow any GNU Social \x28OStatus\x29 followers/mentioners"), $ostatus_autofriend, L10n::t('If you receive a message from an unknown OStatus user, this option decides what to do. If it is checked, a new contact will be created for every unknown user.')],
                        '$default_group' => Group::displayGroupSelection(local_user(), $default_group, L10n::t("Default group for OStatus contacts")),
                        '$legacy_contact' => ['legacy_contact', L10n::t('Your legacy GNU Social account'), $legacy_contact, L10n::t("If you enter your old GNU Social/Statusnet account name here \x28in the format user@domain.tld\x29, your contacts will be added automatically. The field will be emptied when done.")],
index 167a0539758aa2af5e0e5217e1a4d54aced32c25..c2b54821aa8fc8917d145d4228cd297f155bb38b 100644 (file)
@@ -385,6 +385,29 @@ class BBCode extends BaseObject
                return $post;
        }
 
+       /**
+        * Remove [attachment] BBCode and replaces it with a regular [url]
+        *
+        * @param string  $body
+        * @param boolean $no_link_desc No link description
+        *
+        * @return string with replaced body
+        */
+       public static function removeAttachment($body, $no_link_desc = false)
+       {
+               return preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism",
+                       function ($match) use ($no_link_desc) {
+                               $attach_data = self::getAttachmentData($match[0]);
+                               if (empty($attach_data['url'])) {
+                                       return $match[0];
+                               } elseif (empty($attach_data['title']) || $no_link_desc) {
+                                       return '[url]' . $attach_data['url'] . "[/url]\n";
+                               } else {
+                                       return '[url=' . $attach_data['url'] . ']' . $attach_data['title'] . "[/url]\n";
+                               }
+               }, $body);
+       }
+
        /**
         * @brief Converts a BBCode text into plaintext
         *
@@ -600,53 +623,44 @@ class BBCode extends BaseObject
                }
 
                $return = '';
-               if (in_array($simplehtml, [7, 9])) {
-                       // Only add the link when it isn't already part of the body
-                       if (substr_count($text, $data['url']) == 1) {
-                               $return = self::convertUrlForActivityPub($data['url']);
+               try {
+                       if ($tryoembed && OEmbed::isAllowedURL($data['url'])) {
+                               $return = OEmbed::getHTML($data['url'], $data['title']);
+                       } else {
+                               throw new Exception('OEmbed is disabled for this attachment.');
                        }
-               } elseif (($simplehtml != 4) && ($simplehtml != 0)) {
-                       $return = sprintf('<a href="%s" target="_blank">%s</a><br>', $data['url'], $data['title']);
-               } else {
-                       try {
-                               if ($tryoembed && OEmbed::isAllowedURL($data['url'])) {
-                                       $return = OEmbed::getHTML($data['url'], $data['title']);
-                               } else {
-                                       throw new Exception('OEmbed is disabled for this attachment.');
-                               }
-                       } catch (Exception $e) {
-                               $data['title'] = ($data['title'] ?? '') ?: $data['url'];
+               } catch (Exception $e) {
+                       $data['title'] = ($data['title'] ?? '') ?: $data['url'];
 
-                               if ($simplehtml != 4) {
-                                       $return = sprintf('<div class="type-%s">', $data['type']);
-                               }
+                       if ($simplehtml != 4) {
+                               $return = sprintf('<div class="type-%s">', $data['type']);
+                       }
 
-                               if (!empty($data['title']) && !empty($data['url'])) {
-                                       if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
-                                               $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
-                                       } else {
-                                               if (!empty($data['image'])) {
-                                                       $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
-                                               } elseif (!empty($data['preview'])) {
-                                                       $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
-                                               }
-                                               $return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
+                       if (!empty($data['title']) && !empty($data['url'])) {
+                               if (!empty($data['image']) && empty($data['text']) && ($data['type'] == 'photo')) {
+                                       $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a>', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
+                               } else {
+                                       if (!empty($data['image'])) {
+                                               $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $data['url'], self::proxyUrl($data['image'], $simplehtml), $data['title']);
+                                       } elseif (!empty($data['preview'])) {
+                                               $return .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $data['url'], self::proxyUrl($data['preview'], $simplehtml), $data['title']);
                                        }
+                                       $return .= sprintf('<h4><a href="%s">%s</a></h4>', $data['url'], $data['title']);
                                }
+                       }
 
-                               if (!empty($data['description']) && $data['description'] != $data['title']) {
-                                       // Sanitize the HTML by converting it to BBCode
-                                       $bbcode = HTML::toBBCode($data['description']);
-                                       $return .= sprintf('<blockquote>%s</blockquote>', trim(self::convert($bbcode)));
-                               }
+                       if (!empty($data['description']) && $data['description'] != $data['title']) {
+                               // Sanitize the HTML by converting it to BBCode
+                               $bbcode = HTML::toBBCode($data['description']);
+                               $return .= sprintf('<blockquote>%s</blockquote>', trim(self::convert($bbcode)));
+                       }
 
-                               if (!empty($data['url'])) {
-                                       $return .= sprintf('<sup><a href="%s">%s</a></sup>', $data['url'], parse_url($data['url'], PHP_URL_HOST));
-                               }
+                       if (!empty($data['url'])) {
+                               $return .= sprintf('<sup><a href="%s">%s</a></sup>', $data['url'], parse_url($data['url'], PHP_URL_HOST));
+                       }
 
-                               if ($simplehtml != 4) {
-                                       $return .= '</div>';
-                               }
+                       if ($simplehtml != 4) {
+                               $return .= '</div>';
                        }
                }
 
@@ -1222,7 +1236,7 @@ class BBCode extends BaseObject
         * - 5: Unused
         * - 6: Unused
         * - 7: Used for dfrn, OStatus
-        * - 8: Used for WP backlink text setting
+        * - 8: Used for Twitter, WP backlink text setting
         * - 9: ActivityPub
         *
         * @param string $text
@@ -1358,8 +1372,15 @@ class BBCode extends BaseObject
                        } while ($oldtext != $text);
                }
 
+               /// @todo Have a closer look at the different html modes
                // Handle attached links or videos
-               $text = self::convertAttachment($text, $simple_html, $try_oembed);
+               if (in_array($simple_html, [9])) {
+                       $text = self::removeAttachment($text);
+               } elseif (!in_array($simple_html, [0, 4])) {
+                       $text = self::removeAttachment($text, true);
+               } else {
+                       $text = self::convertAttachment($text, $simple_html, $try_oembed);
+               }
 
                // leave open the posibility of [map=something]
                // this is replaced in Item::prepareBody() which has knowledge of the item location
@@ -1749,7 +1770,7 @@ class BBCode extends BaseObject
                 * - #[url=<anything>]<term>[/url]
                 * - [url=<anything>]#<term>[/url]
                 */
-               $text = preg_replace_callback("/(?:#\[url\=.*?\]|\[url\=.*?\]#)(.*?)\[\/url\]/ism", function($matches) {
+               $text = preg_replace_callback("/(?:#\[url\=[^\[\]]*\]|\[url\=[^\[\]]*\]#)(.*?)\[\/url\]/ism", function($matches) {
                        return '#<a href="'
                                . System::baseUrl()     . '/search?tag=' . rawurlencode($matches[1])
                                . '" class="tag" rel="tag" title="' . XML::escape($matches[1]) . '">'
index d759a24dff88f44adf9a6404cfccce754490866b..43aa92f33eec96abf4164f424eed5cd2732189b4 100644 (file)
@@ -1061,12 +1061,12 @@ class GServer
                        $attr = [];
                        if ($node->attributes->length) {
                                foreach ($node->attributes as $attribute) {
-                                       $attribute->value = trim($attribute->value);
-                                       if (empty($attribute->value)) {
+                                       $value = trim($attribute->value);
+                                       if (empty($value)) {
                                                continue;
                                        }
 
-                                       $attr[$attribute->name] = $attribute->value;
+                                       $attr[$attribute->name] = $value;
                                }
 
                                if (empty($attr['name']) || empty($attr['content'])) {
@@ -1117,12 +1117,12 @@ class GServer
                        $attr = [];
                        if ($node->attributes->length) {
                                foreach ($node->attributes as $attribute) {
-                                       $attribute->value = trim($attribute->value);
-                                       if (empty($attribute->value)) {
+                                       $value = trim($attribute->value);
+                                       if (empty($value)) {
                                                continue;
                                        }
 
-                                       $attr[$attribute->name] = $attribute->value;
+                                       $attr[$attribute->name] = $value;
                                }
 
                                if (empty($attr['property']) || empty($attr['content'])) {
index 159fac455b9dd96f33c75da491fab12bda68b351..0b6c1c8bf22620c4c972185ff1d26548ddd07015 100644 (file)
@@ -291,12 +291,10 @@ class Item extends BaseObject
                                $row['object-type'] = Activity\ObjectType::NOTE;
                        }
                } elseif (array_key_exists('verb', $row) && in_array($row['verb'], ['', Activity::POST, Activity::SHARE])) {
-                       // Posts don't have an object or target - but having tags or files.
+                       // Posts don't have a target - but having tags or files.
                        // We safe some performance by building tag and file strings only here.
-                       // We remove object and target since they aren't used for this type.
-                       if (array_key_exists('object', $row)) {
-                               $row['object'] = '';
-                       }
+                       // We remove the target since they aren't used for this type.
+                       // In mail posts we do store some mail header data in the object.
                        if (array_key_exists('target', $row)) {
                                $row['target'] = '';
                        }
index 545ac22c699b0a668cfe486c7d17f617dd01d123..7fc0f5d990957df5181ac929d606e45145b8c0cd 100644 (file)
@@ -498,13 +498,7 @@ class Transmitter
                        }
                }
 
-               $receivers = ['to' => array_values($data['to']), 'cc' => array_values($data['cc']), 'bcc' => array_values($data['bcc'])];
-
-               if (!$blindcopy) {
-                       unset($receivers['bcc']);
-               }
-
-               return $receivers;
+               return ['to' => array_values($data['to']), 'cc' => array_values($data['cc']), 'bcc' => array_values($data['bcc'])];
        }
 
        /**
@@ -653,6 +647,9 @@ class Transmitter
        public static function ItemArrayFromMail($mail_id)
        {
                $mail = DBA::selectFirst('mail', [], ['id' => $mail_id]);
+               if (!DBA::isResult($mail)) {
+                       return [];
+               }
 
                $reply = DBA::selectFirst('mail', ['uri'], ['parent-uri' => $mail['parent-uri'], 'reply' => false]);
 
@@ -696,8 +693,15 @@ class Transmitter
                $mail = self::ItemArrayFromMail($mail_id);
                $object = self::createNote($mail);
 
-               $object['to'] = $object['cc'];
-               unset($object['cc']);
+               if (!empty($object['cc'])) {
+                       $object['to'] = array_merge($object['to'], $object['cc']);
+                       unset($object['cc']);
+               }
+
+               if (!empty($object['bcc'])) {
+                       $object['to'] = array_merge($object['to'], $object['bcc']);
+                       unset($object['bcc']);
+               }
 
                $object['tag'] = [['type' => 'Mention', 'href' => $object['to'][0], 'name' => 'test']];
 
@@ -1020,6 +1024,37 @@ class Transmitter
        {
                $attachments = [];
 
+               // Currently deactivated, since it creates side effects on Mastodon and Pleroma.
+               // It will be reactivated, once this cleared.
+               /*
+               $attach_data = BBCode::getAttachmentData($item['body']);
+               if (!empty($attach_data['url'])) {
+                       $attachment = ['type' => 'Page',
+                               'mediaType' => 'text/html',
+                               'url' => $attach_data['url']];
+
+                       if (!empty($attach_data['title'])) {
+                               $attachment['name'] = $attach_data['title'];
+                       }
+
+                       if (!empty($attach_data['description'])) {
+                               $attachment['summary'] = $attach_data['description'];
+                       }
+
+                       if (!empty($attach_data['image'])) {
+                               $imgdata = Images::getInfoFromURLCached($attach_data['image']);
+                               if ($imgdata) {
+                                       $attachment['icon'] = ['type' => 'Image',
+                                               'mediaType' => $imgdata['mime'],
+                                               'width' => $imgdata[0],
+                                               'height' => $imgdata[1],
+                                               'url' => $attach_data['image']];
+                               }
+                       }
+
+                       $attachments[] = $attachment;
+               }
+               */
                $arr = explode('[/attach],', $item['attach']);
                if (count($arr)) {
                        foreach ($arr as $r) {
@@ -1203,6 +1238,10 @@ class Transmitter
         */
        public static function createNote($item)
        {
+               if (empty($item)) {
+                       return [];
+               }
+
                if ($item['event-type'] == 'event') {
                        $type = 'Event';
                } elseif (!empty($item['title'])) {
@@ -1272,6 +1311,7 @@ class Transmitter
 
                $regexp = "/[@!]\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
                $richbody = preg_replace_callback($regexp, ['self', 'mentionCallback'], $item['body']);
+               $richbody = BBCode::removeAttachment($richbody);
 
                $data['contentMap']['text/html'] = BBCode::convert($richbody, false);
                $data['contentMap']['text/markdown'] = BBCode::toMarkdown($item["body"]);
index e8c576a94cd09c7dd3cd147a9b3514437d5b989e..7c583dc280947ad6cafa5ea8fa7b6e46f8e6f480 100644 (file)
@@ -3419,7 +3419,7 @@ class Diaspora
                        $condition = ['guid' => $guid, 'network' => [Protocol::DFRN, Protocol::DIASPORA]];
                        $item = Item::selectFirst(['contact-id'], $condition);
                        if (DBA::isResult($item)) {
-                               $ret= [];
+                               $ret = [];
                                $ret["root_handle"] = self::handleFromContact($item["contact-id"]);
                                $ret["root_guid"] = $guid;
                                return $ret;
@@ -3445,12 +3445,12 @@ class Diaspora
                        $profile = $matches[1];
                }
 
-               $ret= [];
+               $ret = [];
 
-               if ($profile != "") {
-                       if (Contact::getIdForURL($profile)) {
-                               $author = Contact::getDetailsByURL($profile);
-                               $ret["root_handle"] = $author['addr'];
+               if (!empty($profile) && ($cid = Contact::getIdForURL($profile))) {
+                       $contact = DBA::selectFirst('contact', ['addr'], ['id' => $cid]);
+                       if (!empty($contact['addr'])) {
+                               $ret['root_handle'] = $contact['addr'];
                        }
                }
 
@@ -3584,6 +3584,14 @@ class Diaspora
                        $title = $item["title"];
                        $body = $item["body"];
 
+                       // Fetch the title from an attached link - if there is one
+                       if (empty($item["title"]) && PConfig::get($owner['uid'], 'system', 'attach_link_title')) {
+                               $page_data = BBCode::getAttachmentData($item['body']);
+                               if (!empty($page_data['type']) && !empty($page_data['title']) && ($page_data['type'] == 'link')) {
+                                       $title = $page_data['title'];
+                               }
+                       }
+
                        if ($item['author-link'] != $item['owner-link']) {
                                require_once 'mod/share.php';
                                $body = share_header($item['author-name'], $item['author-link'], $item['author-avatar'],
@@ -3595,7 +3603,7 @@ class Diaspora
 
                        // Adding the title
                        if (strlen($title)) {
-                               $body = "## ".html_entity_decode($title)."\n\n".$body;
+                               $body = "### ".html_entity_decode($title)."\n\n".$body;
                        }
 
                        if ($item["attach"]) {
index 06cf8612502ae65679019ef197acbfafa96f6570..3df39af00719e80da3b7f41dd7fb5fa417c6b7cd 100644 (file)
@@ -4,6 +4,7 @@
  */
 namespace Friendica\Protocol;
 
+use Friendica\Core\Hook;
 use Friendica\Core\Logger;
 use Friendica\Content\Text\HTML;
 use Friendica\Model\Item;
@@ -126,6 +127,10 @@ class Email
                        if (trim($ret['body']) == '') {
                                $ret['body'] = self::messageGetPart($mbox, $uid, $struc, 0, 'plain');
                        } else {
+                               $message = ['text' => '', 'html' => $ret['body']];
+                               Hook::callAll('email_getmessage', $message);
+                               $ret['body'] = $message['html'];
+
                                $ret['body'] = HTML::toBBCode($ret['body']);
                        }
                } else {
@@ -142,7 +147,13 @@ class Email
                                        $html .= $x;
                                }
                        }
-                       if (trim($html) != '') {
+
+                       $message = ['text' => trim($text), 'html' => trim($html)];
+                       Hook::callAll('email_getmessage', $message);
+                       $html = $message['html'];
+                       $text = $message['text'];
+
+                       if (!empty($html)) {
                                $ret['body'] = HTML::toBBCode($html);
                        } else {
                                $ret['body'] = $text;
@@ -160,12 +171,14 @@ class Email
 
                $ret['body'] = self::unifyAttributionLine($ret['body']);
 
+               Hook::callAll('email_getmessage_end', $ret);
+
                return $ret;
        }
 
-       // At the moment - only return plain/text.
-       // Later we'll repackage inline images as data url's and make the HTML safe
        /**
+        * fetch the specified message part number with the specified subtype
+        *
         * @param resource $mbox    mailbox
         * @param integer  $uid     user id
         * @param object   $p       parts
index b7e7ce9201ebdbd7099027c28a3ce39b2bbb596d..705a094c38149b433b454fc2b5626181ebb9b598 100644 (file)
@@ -15,6 +15,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
 use Friendica\Protocol\ActivityNamespace;
+use Friendica\Util\ParseUrl;
 use Friendica\Util\Network;
 use Friendica\Util\XML;
 
@@ -399,7 +400,7 @@ class Feed {
 
                                // Remove a possible link to the item itself
                                $item["body"] = str_replace($item["plink"], '', $item["body"]);
-                               $item["body"] = preg_replace('/\[url\=\](\w+.*?)\[\/url\]/i', '', $item["body"]);
+                               $item["body"] = trim(preg_replace('/\[url\=\](\w+.*?)\[\/url\]/i', '', $item["body"]));
 
                                // Replace the content when the title is longer than the body
                                $replace = (strlen($item["title"]) > strlen($item["body"]));
@@ -415,8 +416,21 @@ class Feed {
                                }
 
                                if ($replace) {
-                                       $item["body"] = $item["title"];
+                                       $item["body"] = trim($item["title"]);
                                }
+
+                               $data = ParseUrl::getSiteinfoCached($item['plink'], true);
+                               if (!empty($data['text']) && !empty($data['title']) && (mb_strlen($item['body']) < mb_strlen($data['text']))) {
+                                       // When the fetched page info text is longer than the body, we do try to enhance the body
+                                       if (!empty($item['body']) && (strpos($data['title'], $item['body']) === false) && (strpos($data['text'], $item['body']) === false)) {
+                                               // The body is not part of the fetched page info title or page info text. So we add the text to the body
+                                               $item['body'] .= "\n\n" . $data['text'];
+                                       } else {
+                                               // Else we replace the body with the page info text
+                                               $item['body'] = $data['text'];
+                                       }
+                               }
+
                                // We always strip the title since it will be added in the page information
                                $item["title"] = "";
                                $item["body"] = $item["body"].add_page_info($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
index 1f8fbdeabe4e8898d2a4442196a46a2093c2afd3..569136e6d13da5b67ebfd16f94a7823747326f45 100644 (file)
@@ -17,6 +17,16 @@ use Friendica\Database\DBA;
  */
 class ParseUrl
 {
+       /**
+        * Maximum number of characters for the description
+        */
+       const MAX_DESC_COUNT = 250;
+
+       /**
+        * Minimum number of characters for the description
+        */
+       const MIN_DESC_COUNT = 100;
+
        /**
         * @brief Search for chached embeddable data of an url otherwise fetch it
         *
@@ -336,36 +346,7 @@ class ParseUrl
                        $siteinfo['type'] = 'link';
                }
 
-               if (empty($siteinfo['image']) && !$no_guessing) {
-                       $list = $xpath->query('//img[@src]');
-                       foreach ($list as $node) {
-                               $img_tag = [];
-                               if ($node->attributes->length) {
-                                       foreach ($node->attributes as $attribute) {
-                                               $img_tag[$attribute->name] = $attribute->value;
-                                       }
-                               }
-
-                               $src = self::completeUrl($img_tag['src'], $url);
-                               $photodata = Images::getInfoFromURLCached($src);
-
-                               if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) {
-                                       if ($photodata[0] > 300) {
-                                               $photodata[1] = round($photodata[1] * (300 / $photodata[0]));
-                                               $photodata[0] = 300;
-                                       }
-                                       if ($photodata[1] > 300) {
-                                               $photodata[0] = round($photodata[0] * (300 / $photodata[1]));
-                                               $photodata[1] = 300;
-                                       }
-                                       $siteinfo['images'][] = [
-                                               'src'    => $src,
-                                               'width'  => $photodata[0],
-                                               'height' => $photodata[1]
-                                       ];
-                               }
-                       }
-               } elseif (!empty($siteinfo['image'])) {
+               if (!empty($siteinfo['image'])) {
                        $src = self::completeUrl($siteinfo['image'], $url);
 
                        unset($siteinfo['image']);
@@ -379,47 +360,15 @@ class ParseUrl
                        }
                }
 
-               if ((@$siteinfo['text'] == '') && (@$siteinfo['title'] != '') && !$no_guessing) {
-                       $text = '';
-
-                       $list = $xpath->query('//div[@class="article"]');
-                       foreach ($list as $node) {
-                               if (strlen($node->nodeValue) > 40) {
-                                       $text .= ' ' . trim($node->nodeValue);
-                               }
-                       }
-
-                       if ($text == '') {
-                               $list = $xpath->query('//div[@class="content"]');
-                               foreach ($list as $node) {
-                                       if (strlen($node->nodeValue) > 40) {
-                                               $text .= ' ' . trim($node->nodeValue);
-                                       }
-                               }
-                       }
-
-                       // If none text was found then take the paragraph content
-                       if ($text == '') {
-                               $list = $xpath->query('//p');
-                               foreach ($list as $node) {
-                                       if (strlen($node->nodeValue) > 40) {
-                                               $text .= ' ' . trim($node->nodeValue);
-                                       }
-                               }
-                       }
-
-                       if ($text != '') {
-                               $text = trim(str_replace(["\n", "\r"], [' ', ' '], $text));
-
-                               while (strpos($text, '  ')) {
-                                       $text = trim(str_replace('  ', ' ', $text));
-                               }
-
-                               $siteinfo['text'] = trim(html_entity_decode(substr($text, 0, 350), ENT_QUOTES, 'UTF-8') . '...');
+               if (!empty($siteinfo['text']) && mb_strlen($siteinfo['text']) > self::MAX_DESC_COUNT) {
+                       $siteinfo['text'] = mb_substr($siteinfo['text'], 0, self::MAX_DESC_COUNT) . '…';
+                       $pos = mb_strrpos($siteinfo['text'], '.');
+                       if ($pos > self::MIN_DESC_COUNT) {
+                               $siteinfo['text'] = mb_substr($siteinfo['text'], 0, $pos + 1);
                        }
                }
 
-               Logger::log('Siteinfo for ' . $url . ' ' . print_r($siteinfo, true), Logger::DEBUG);
+               Logger::info('Siteinfo fetched', ['url' => $url, 'siteinfo' => $siteinfo]);
 
                Hook::callAll('getsiteinfo', $siteinfo);
 
index 8b6be76b50dad5fe3a25da132a798bd4455b0e68..3e4efb5f3c4877568d913b84a3095eb0c0c0da35 100644 (file)
@@ -51,6 +51,8 @@ class Notifier
 
                $delivery_contacts_stmt = null;
                $target_item = [];
+               $parent = [];
+               $thr_parent = [];
                $items = [];
                $delivery_queue_count = 0;
 
@@ -594,6 +596,10 @@ class Notifier
         */
        private static function skipDFRN($contact, $item, $parent, $thr_parent, $cmd)
        {
+               if (empty($parent['network'])) {
+                       return false;
+               }
+
                // Don't skip when the starting post is delivered via Diaspora
                if ($parent['network'] == Protocol::DIASPORA) {
                        return false;
index 3f8b98ead1e391854b5e6b8543e64562202931ed..fefe7d8020b451130d06e444c80b372734368ef7 100644 (file)
@@ -539,9 +539,9 @@ class OnePoll
                                        }
 
                                        // look for a 'references' or an 'in-reply-to' header and try to match with a parent item we have locally.
-                                       $raw_refs = ((property_exists($meta, 'references')) ? str_replace("\t", '', $meta->references) : '');
+                                       $raw_refs = (property_exists($meta, 'references') ? str_replace("\t", '', $meta->references) : '');
                                        if (!trim($raw_refs)) {
-                                               $raw_refs = ((property_exists($meta, 'in_reply_to')) ? str_replace("\t", '', $meta->in_reply_to) : '');
+                                               $raw_refs = (property_exists($meta, 'in_reply_to') ? str_replace("\t", '', $meta->in_reply_to) : '');
                                        }
                                        $raw_refs = trim($raw_refs);  // Don't allow a blank reference in $refs_arr
 
@@ -601,31 +601,38 @@ class OnePoll
                                                Logger::log("Mail: can't fetch msg ".$msg_uid." for ".$mailconf['user']);
                                                continue;
                                        }
+
                                        $datarray['body'] = Strings::escapeHtml($r['body']);
                                        $datarray['body'] = BBCode::limitBodySize($datarray['body']);
 
                                        Logger::log("Mail: Importing ".$msg_uid." for ".$mailconf['user']);
 
-                                       /// @TODO Adding a gravatar for the original author would be cool
+                                       $headers = imap_headerinfo($mbox, $meta->msgno);
+                                       $object = [];
 
-                                       $from = imap_mime_header_decode($meta->from);
-                                       $fromdecoded = "";
-                                       foreach ($from as $frompart) {
-                                               if ($frompart->charset != "default") {
-                                                       $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
-                                               } else {
-                                                       $fromdecoded .= $frompart->text;
-                                               }
+                                       if (!empty($headers->from)) {
+                                               $object['from'] = $headers->from;
                                        }
 
-                                       $fromarr = imap_rfc822_parse_adrlist($fromdecoded, BaseObject::getApp()->getHostName());
+                                       if (!empty($headers->to)) {
+                                               $object['to'] = $headers->to;
+                                       }
 
-                                       $frommail = $fromarr[0]->mailbox."@".$fromarr[0]->host;
+                                       if (!empty($headers->reply_to)) {
+                                               $object['reply_to'] = $headers->reply_to;
+                                       }
+
+                                       if (!empty($headers->sender)) {
+                                               $object['sender'] = $headers->sender;
+                                       }
+
+                                       if (!empty($object)) {
+                                               $datarray['object'] = json_encode($object);
+                                       }
 
-                                       if (isset($fromarr[0]->personal)) {
-                                               $fromname = $fromarr[0]->personal;
-                                       } else {
-                                               $fromname = $frommail;
+                                       $fromname = $frommail = $headers->from[0]->mailbox . '@' . $headers->from[0]->host;
+                                       if (!empty($headers->from[0]->personal)) {
+                                               $fromname = $headers->from[0]->personal;
                                        }
 
                                        $datarray['author-name'] = $fromname;
index 28f9ffab198c80701fee3264768d527c4099876b..53b4beaad3dfd4fd0b5f665693b9b9496e62b6fe 100644 (file)
@@ -14,6 +14,7 @@
        {{include file="field_checkbox.tpl" field=$accept_only_sharer}}
        {{include file="field_checkbox.tpl" field=$disable_cw}}
        {{include file="field_checkbox.tpl" field=$no_intelligent_shortening}}
+       {{include file="field_checkbox.tpl" field=$attach_link_title}}
        {{include file="field_checkbox.tpl" field=$ostatus_autofriend}}
        {{$default_group nofilter}}
        {{include file="field_input.tpl" field=$legacy_contact}}
index 30c2ca6b4af360b80805315c89a29b28af222476..92d2ed861e5e498f96fcd1e87df7eedb472e72a1 100644 (file)
@@ -26,6 +26,8 @@
 
                                                {{include file="field_checkbox.tpl" field=$no_intelligent_shortening}}
 
+                                               {{include file="field_checkbox.tpl" field=$attach_link_title}}
+
                                                {{include file="field_checkbox.tpl" field=$ostatus_autofriend}}
 
                                                {{$default_group nofilter}}