]> git.mxchange.org Git - friendica.git/blobdiff - src/Module/Contact.php
Remove queue from Admin/Summary
[friendica.git] / src / Module / Contact.php
index b7e182dc1461d2ef3caac612fb87ad5143afe905..847455f498927f0d6444c5a88dcbc858cd780c18 100644 (file)
@@ -10,7 +10,7 @@ use Friendica\Content\Pager;
 use Friendica\Content\Text\BBCode;
 use Friendica\Content\Widget;
 use Friendica\Core\ACL;
-use Friendica\Core\Addon;
+use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
@@ -18,7 +18,8 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model;
-use Friendica\Module\Login;
+use Friendica\Network\HTTPException\BadRequestException;
+use Friendica\Network\HTTPException\NotFoundException;
 use Friendica\Network\Probe;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
@@ -31,106 +32,6 @@ use Friendica\Util\Strings;
  */
 class Contact extends BaseModule
 {
-       public static function init()
-       {
-               $a = self::getApp();
-
-               if (!local_user()) {
-                       return;
-               }
-
-               $nets = defaults($_GET, 'nets', '');
-               if ($nets == 'all') {
-                       $nets = '';
-               }
-
-               if (!x($a->page, 'aside')) {
-                       $a->page['aside'] = '';
-               }
-
-               $contact_id = null;
-               $contact = null;
-               if ($a->argc == 2 && intval($a->argv[1])
-                       || $a->argc == 3 && intval($a->argv[1]) && in_array($a->argv[2], ['posts', 'conversations'])
-               ) {
-                       $contact_id = intval($a->argv[1]);
-                       $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user()]);
-
-                       if (!DBA::isResult($contact)) {
-                               $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => 0]);
-                       }
-
-                       // Don't display contacts that are about to be deleted
-                       if ($contact['network'] == Protocol::PHANTOM) {
-                               $contact = false;
-                       }
-               }
-
-               if (DBA::isResult($contact)) {
-                       if ($contact['self']) {
-                               if (($a->argc == 3) && intval($a->argv[1]) && in_array($a->argv[2], ['posts', 'conversations'])) {
-                                       $a->internalRedirect('profile/' . $contact['nick']);
-                               } else {
-                                       $a->internalRedirect('profile/' . $contact['nick'] . '?tab=profile');
-                               }
-                       }
-
-                       $a->data['contact'] = $contact;
-
-                       if (($contact['network'] != '') && ($contact['network'] != Protocol::DFRN)) {
-                               $networkname = Strings::formatNetworkName($contact['network'], $contact['url']);
-                       } else {
-                               $networkname = '';
-                       }
-
-                       /// @TODO Add nice spaces
-                       $vcard_widget = Renderer::replaceMacros(Renderer::getMarkupTemplate('vcard-widget.tpl'), [
-                               '$name'         => htmlentities($contact['name']),
-                               '$photo'        => $contact['photo'],
-                               '$url'          => Model\Contact::MagicLink($contact['url']),
-                               '$addr'         => defaults($contact, 'addr', ''),
-                               '$network_name' => $networkname,
-                               '$network'      => L10n::t('Network:'),
-                               '$account_type' => Model\Contact::getAccountType($contact)
-                       ]);
-
-                       $findpeople_widget = '';
-                       $follow_widget = '';
-                       $networks_widget = '';
-               } else {
-                       $vcard_widget = '';
-                       $networks_widget = Widget::networks('contact', $nets);
-                       if (isset($_GET['add'])) {
-                               $follow_widget = Widget::follow($_GET['add']);
-                       } else {
-                               $follow_widget = Widget::follow();
-                       }
-
-                       $findpeople_widget = Widget::findPeople();
-               }
-
-               if ($contact['uid'] != 0) {
-                       $groups_widget = Model\Group::sidebarWidget('contact', 'group', 'full', 'everyone', $contact_id);
-               } else {
-                       $groups_widget = null;
-               }
-
-               $a->page['aside'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('contacts-widget-sidebar.tpl'), [
-                       '$vcard_widget'      => $vcard_widget,
-                       '$findpeople_widget' => $findpeople_widget,
-                       '$follow_widget'     => $follow_widget,
-                       '$groups_widget'     => $groups_widget,
-                       '$networks_widget'   => $networks_widget
-               ]);
-
-               $base = $a->getBaseURL();
-               $tpl = Renderer::getMarkupTemplate('contacts-head.tpl');
-               $a->page['htmlhead'] .= Renderer::replaceMacros($tpl, [
-                       '$baseurl' => System::baseUrl(true),
-                       '$base' => $base
-               ]);
-       }
-
        private static function batchActions(App $a)
        {
                if (empty($_POST['contact_batch']) || !is_array($_POST['contact_batch'])) {
@@ -139,7 +40,7 @@ class Contact extends BaseModule
 
                $contacts_id = $_POST['contact_batch'];
 
-               $stmt = DBA::select('contact', ['id', 'archive'], ['id' => $contacts_id, 'uid' => local_user(), 'self' => false]);
+               $stmt = DBA::select('contact', ['id', 'archive'], ['id' => $contacts_id, 'uid' => local_user(), 'self' => false, 'deleted' => false]);
                $orig_records = DBA::toArray($stmt);
 
                $count_actions = 0;
@@ -182,23 +83,25 @@ class Contact extends BaseModule
                        return;
                }
 
+               // @TODO: Replace with parameter from router
                if ($a->argv[1] === 'batch') {
                        self::batchActions($a);
                        return;
                }
 
+               // @TODO: Replace with parameter from router
                $contact_id = intval($a->argv[1]);
                if (!$contact_id) {
                        return;
                }
 
-               if (!DBA::exists('contact', ['id' => $contact_id, 'uid' => local_user()])) {
+               if (!DBA::exists('contact', ['id' => $contact_id, 'uid' => local_user(), 'deleted' => false])) {
                        notice(L10n::t('Could not access contact record.') . EOL);
                        $a->internalRedirect('contact');
                        return; // NOTREACHED
                }
 
-               Addon::callHooks('contact_edit_post', $_POST);
+               Hook::callAll('contact_edit_post', $_POST);
 
                $profile_id = intval(defaults($_POST, 'profile-assign', 0));
                if ($profile_id) {
@@ -221,7 +124,7 @@ class Contact extends BaseModule
                        $priority = 0;
                }
 
-               $info = Strings::escapeHtml(trim($_POST['info']));
+               $info = Strings::escapeHtml(trim(defaults($_POST, 'info', '')));
 
                $r = DBA::update('contact', [
                        'profile-id' => $profile_id,
@@ -240,7 +143,7 @@ class Contact extends BaseModule
                        notice(L10n::t('Failed to update contact record.') . EOL);
                }
 
-               $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user()]);
+               $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user(), 'deleted' => false]);
                if (DBA::isResult($contact)) {
                        $a->data['contact'] = $contact;
                }
@@ -252,7 +155,7 @@ class Contact extends BaseModule
 
        private static function updateContactFromPoll($contact_id)
        {
-               $contact = DBA::selectFirst('contact', ['uid', 'url', 'network'], ['id' => $contact_id, 'uid' => local_user()]);
+               $contact = DBA::selectFirst('contact', ['uid', 'url', 'network'], ['id' => $contact_id, 'uid' => local_user(), 'deleted' => false]);
                if (!DBA::isResult($contact)) {
                        return;
                }
@@ -273,7 +176,7 @@ class Contact extends BaseModule
 
        private static function updateContactFromProbe($contact_id)
        {
-               $contact = DBA::selectFirst('contact', ['uid', 'url', 'network'], ['id' => $contact_id, 'uid' => local_user()]);
+               $contact = DBA::selectFirst('contact', ['uid', 'url', 'network'], ['id' => $contact_id, 'uid' => local_user(), 'deleted' => false]);
                if (!DBA::isResult($contact)) {
                        return;
                }
@@ -314,7 +217,7 @@ class Contact extends BaseModule
                        return;
                }
 
-               $r = DBA::update('contact', $fields, ['id' => $contact_id, 'uid' => local_user()]);
+               DBA::update('contact', $fields, ['id' => $contact_id, 'uid' => local_user()]);
 
                // Update the entry in the contact table
                Model\Contact::updateAvatar($data['photo'], local_user(), $contact_id, true);
@@ -356,7 +259,96 @@ class Contact extends BaseModule
 
        public static function content($update = 0)
        {
+               if (!local_user()) {
+                       return Login::form($_SERVER['REQUEST_URI']);
+               }
+
                $a = self::getApp();
+
+               $nets = defaults($_GET, 'nets', '');
+               $rel  = defaults($_GET, 'rel' , '');
+
+               if (empty($a->page['aside'])) {
+                       $a->page['aside'] = '';
+               }
+
+               $contact_id = null;
+               $contact = null;
+               // @TODO: Replace with parameter from router
+               if ($a->argc == 2 && intval($a->argv[1])
+                       || $a->argc == 3 && intval($a->argv[1]) && in_array($a->argv[2], ['posts', 'conversations'])
+               ) {
+                       $contact_id = intval($a->argv[1]);
+                       $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => local_user(), 'deleted' => false]);
+
+                       if (!DBA::isResult($contact)) {
+                               $contact = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => 0, 'deleted' => false]);
+                       }
+
+                       // Don't display contacts that are about to be deleted
+                       if ($contact['network'] == Protocol::PHANTOM) {
+                               $contact = false;
+                       }
+               }
+
+               if (DBA::isResult($contact)) {
+                       if ($contact['self']) {
+                               // @TODO: Replace with parameter from router
+                               if (($a->argc == 3) && intval($a->argv[1]) && in_array($a->argv[2], ['posts', 'conversations'])) {
+                                       $a->internalRedirect('profile/' . $contact['nick']);
+                               } else {
+                                       $a->internalRedirect('profile/' . $contact['nick'] . '?tab=profile');
+                               }
+                       }
+
+                       $a->data['contact'] = $contact;
+
+                       if (($contact['network'] != '') && ($contact['network'] != Protocol::DFRN)) {
+                               $network_link = Strings::formatNetworkName($contact['network'], $contact['url']);
+                       } else {
+                               $network_link = '';
+                       }
+
+                       $vcard_widget = Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/vcard.tpl'), [
+                               '$name'         => $contact['name'],
+                               '$photo'        => $contact['photo'],
+                               '$url'          => Model\Contact::magicLinkByContact($contact, $contact['url']),
+                               '$addr'         => defaults($contact, 'addr', ''),
+                               '$network_link' => $network_link,
+                               '$network'      => L10n::t('Network:'),
+                               '$account_type' => Model\Contact::getAccountType($contact)
+                       ]);
+
+                       $findpeople_widget = '';
+                       $follow_widget = '';
+                       $networks_widget = '';
+                       $rel_widget = '';
+               } else {
+                       $vcard_widget = '';
+                       $findpeople_widget = Widget::findPeople();
+                       if (isset($_GET['add'])) {
+                               $follow_widget = Widget::follow($_GET['add']);
+                       } else {
+                               $follow_widget = Widget::follow();
+                       }
+
+                       $networks_widget = Widget::networks($_SERVER['REQUEST_URI'], $nets);
+                       $rel_widget = Widget::contactRels($_SERVER['REQUEST_URI'], $rel);
+               }
+
+               if ($contact['uid'] != 0) {
+                       $groups_widget = Model\Group::sidebarWidget('contact', 'group', 'full', 'everyone', $contact_id);
+               } else {
+                       $groups_widget = null;
+               }
+
+               $a->page['aside'] .= $vcard_widget . $findpeople_widget . $follow_widget . $groups_widget . $networks_widget . $rel_widget;
+
+               $tpl = Renderer::getMarkupTemplate('contacts-head.tpl');
+               $a->page['htmlhead'] .= Renderer::replaceMacros($tpl, [
+                       '$baseurl' => $a->getBaseURL(true),
+               ]);
+
                $sort_type = 0;
                $o = '';
                Nav::setSelected('contact');
@@ -369,16 +361,15 @@ class Contact extends BaseModule
                if ($a->argc == 3) {
                        $contact_id = intval($a->argv[1]);
                        if (!$contact_id) {
-                               return;
+                               throw new BadRequestException();
                        }
 
+                       // @TODO: Replace with parameter from router
                        $cmd = $a->argv[2];
 
-                       $orig_record = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => [0, local_user()], 'self' => false]);
+                       $orig_record = DBA::selectFirst('contact', [], ['id' => $contact_id, 'uid' => [0, local_user()], 'self' => false, 'deleted' => false]);
                        if (!DBA::isResult($orig_record)) {
-                               notice(L10n::t('Could not access contact record.') . EOL);
-                               $a->internalRedirect('contact');
-                               return; // NOTREACHED
+                               throw new NotFoundException(L10n::t('Contact not found'));
                        }
 
                        if ($cmd === 'update' && ($orig_record['uid'] != 0)) {
@@ -400,7 +391,7 @@ class Contact extends BaseModule
                                info(($blocked ? L10n::t('Contact has been blocked') : L10n::t('Contact has been unblocked')) . EOL);
 
                                $a->internalRedirect('contact/' . $contact_id);
-                               return; // NOTREACHED
+                               // NOTREACHED
                        }
 
                        if ($cmd === 'ignore') {
@@ -410,7 +401,7 @@ class Contact extends BaseModule
                                info(($ignored ? L10n::t('Contact has been ignored') : L10n::t('Contact has been unignored')) . EOL);
 
                                $a->internalRedirect('contact/' . $contact_id);
-                               return; // NOTREACHED
+                               // NOTREACHED
                        }
 
                        if ($cmd === 'archive' && ($orig_record['uid'] != 0)) {
@@ -421,7 +412,7 @@ class Contact extends BaseModule
                                }
 
                                $a->internalRedirect('contact/' . $contact_id);
-                               return; // NOTREACHED
+                               // NOTREACHED
                        }
 
                        if ($cmd === 'drop' && ($orig_record['uid'] != 0)) {
@@ -461,7 +452,7 @@ class Contact extends BaseModule
                                info(L10n::t('Contact has been removed.') . EOL);
 
                                $a->internalRedirect('contact');
-                               return; // NOTREACHED
+                               // NOTREACHED
                        }
                        if ($cmd === 'posts') {
                                return self::getPostsHTML($a, $contact_id);
@@ -474,7 +465,6 @@ class Contact extends BaseModule
                $_SESSION['return_path'] = $a->query_string;
 
                if (!empty($a->data['contact']) && is_array($a->data['contact'])) {
-                       $contact_id = $a->data['contact']['id'];
                        $contact = $a->data['contact'];
 
                        $a->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('contact_head.tpl'), [
@@ -514,7 +504,7 @@ class Contact extends BaseModule
                                $relation_text = '';
                        }
 
-                       $relation_text = sprintf($relation_text, htmlentities($contact['name']));
+                       $relation_text = sprintf($relation_text, $contact['name']);
 
                        $url = Model\Contact::magicLink($contact['url']);
                        if (strpos($url, 'redir/') === 0) {
@@ -570,12 +560,12 @@ class Contact extends BaseModule
                        /// @todo Only show the following link with DFRN when the remote version supports it
                        $follow = '';
                        $follow_text = '';
-                       if (in_array($contact['rel'], [Model\Contact::FRIEND, Model\Contact::SHARING])) {
+                       if ($contact['uid'] && in_array($contact['rel'], [Model\Contact::FRIEND, Model\Contact::SHARING])) {
                                if (in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
                                        $follow = $a->getBaseURL(true) . '/unfollow?url=' . urlencode($contact['url']);
                                        $follow_text = L10n::t('Disconnect/Unfollow');
                                }
-                       } else {
+                       } elseif(!$contact['pending']) {
                                $follow = $a->getBaseURL(true) . '/follow?url=' . urlencode($contact['url']);
                                $follow_text = L10n::t('Connect/Follow');
                        }
@@ -636,10 +626,9 @@ class Contact extends BaseModule
                                '$hidden'         => ['hidden', L10n::t('Hide this contact from others'), ($contact['hidden'] == 1), L10n::t('Replies/likes to your public posts <strong>may</strong> still be visible')],
                                '$notify'         => ['notify', L10n::t('Notification for new posts'), ($contact['notify_new_posts'] == 1), L10n::t('Send a notification of every new post of this contact')],
                                '$fetch_further_information' => $fetch_further_information,
-                               '$ffi_keyword_blacklist' => $contact['ffi_keyword_blacklist'],
                                '$ffi_keyword_blacklist' => ['ffi_keyword_blacklist', L10n::t('Blacklisted keywords'), $contact['ffi_keyword_blacklist'], L10n::t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')],
                                '$photo'          => $contact['photo'],
-                               '$name'           => htmlentities($contact['name']),
+                               '$name'           => $contact['name'],
                                '$dir_icon'       => $dir_icon,
                                '$sparkle'        => $sparkle,
                                '$url'            => $url,
@@ -663,70 +652,50 @@ class Contact extends BaseModule
 
                        $arr = ['contact' => $contact, 'output' => $o];
 
-                       Addon::callHooks('contact_edit', $arr);
+                       Hook::callAll('contact_edit', $arr);
 
                        return $arr['output'];
                }
 
-               $blocked = false;
-               $hidden = false;
-               $ignored = false;
-               $archived = false;
-               $all = false;
-
-               if (($a->argc == 2) && ($a->argv[1] === 'all')) {
-                       $sql_extra = '';
-                       $all = true;
-               } elseif (($a->argc == 2) && ($a->argv[1] === 'blocked')) {
-                       $sql_extra = " AND `blocked` = 1 ";
-                       $blocked = true;
-               } elseif (($a->argc == 2) && ($a->argv[1] === 'hidden')) {
-                       $sql_extra = " AND `hidden` = 1 ";
-                       $hidden = true;
-               } elseif (($a->argc == 2) && ($a->argv[1] === 'ignored')) {
-                       $sql_extra = " AND `readonly` = 1 ";
-                       $ignored = true;
-               } elseif (($a->argc == 2) && ($a->argv[1] === 'archived')) {
-                       $sql_extra = " AND `archive` = 1 ";
-                       $archived = true;
-               } else {
-                       $sql_extra = " AND `blocked` = 0 ";
+               // @TODO: Replace with parameter from router
+               $type = defaults($a->argv, 1, '');
+
+               switch ($type) {
+                       case 'blocked':
+                               $sql_extra = " AND `blocked` = 1";
+                               break;
+                       case 'hidden':
+                               $sql_extra = " AND `hidden` = 1 AND `blocked` = 0";
+                               break;
+                       case 'ignored':
+                               $sql_extra = " AND `readonly` = 1 AND `blocked` = 0";
+                               break;
+                       case 'archived':
+                               $sql_extra = " AND `archive` = 1 AND `blocked` = 0";
+                               break;
+                       default:
+                               $sql_extra = " AND `blocked` = 0";
                }
 
                $sql_extra .= sprintf(" AND `network` != '%s' ", Protocol::PHANTOM);
 
                $search = Strings::escapeTags(trim(defaults($_GET, 'search', '')));
                $nets   = Strings::escapeTags(trim(defaults($_GET, 'nets'  , '')));
+               $rel    = Strings::escapeTags(trim(defaults($_GET, 'rel'   , '')));
 
                $tabs = [
-                       [
-                               'label' => L10n::t('Suggestions'),
-                               'url'   => 'suggest',
-                               'sel'   => '',
-                               'title' => L10n::t('Suggest potential friends'),
-                               'id'    => 'suggestions-tab',
-                               'accesskey' => 'g',
-                       ],
                        [
                                'label' => L10n::t('All Contacts'),
-                               'url'   => 'contact/all',
-                               'sel'   => ($all) ? 'active' : '',
+                               'url'   => 'contact',
+                               'sel'   => !$type ? 'active' : '',
                                'title' => L10n::t('Show all contacts'),
                                'id'    => 'showall-tab',
                                'accesskey' => 'l',
                        ],
-                       [
-                               'label' => L10n::t('Unblocked'),
-                               'url'   => 'contact',
-                               'sel'   => ((!$all) && (!$blocked) && (!$hidden) && (!$search) && (!$nets) && (!$ignored) && (!$archived)) ? 'active' : '',
-                               'title' => L10n::t('Only show unblocked contacts'),
-                               'id'    => 'showunblocked-tab',
-                               'accesskey' => 'o',
-                       ],
                        [
                                'label' => L10n::t('Blocked'),
                                'url'   => 'contact/blocked',
-                               'sel'   => ($blocked) ? 'active' : '',
+                               'sel'   => $type == 'blocked' ? 'active' : '',
                                'title' => L10n::t('Only show blocked contacts'),
                                'id'    => 'showblocked-tab',
                                'accesskey' => 'b',
@@ -734,7 +703,7 @@ class Contact extends BaseModule
                        [
                                'label' => L10n::t('Ignored'),
                                'url'   => 'contact/ignored',
-                               'sel'   => ($ignored) ? 'active' : '',
+                               'sel'   => $type == 'ignored' ? 'active' : '',
                                'title' => L10n::t('Only show ignored contacts'),
                                'id'    => 'showignored-tab',
                                'accesskey' => 'i',
@@ -742,7 +711,7 @@ class Contact extends BaseModule
                        [
                                'label' => L10n::t('Archived'),
                                'url'   => 'contact/archived',
-                               'sel'   => ($archived) ? 'active' : '',
+                               'sel'   => $type == 'archived' ? 'active' : '',
                                'title' => L10n::t('Only show archived contacts'),
                                'id'    => 'showarchived-tab',
                                'accesskey' => 'y',
@@ -750,11 +719,19 @@ class Contact extends BaseModule
                        [
                                'label' => L10n::t('Hidden'),
                                'url'   => 'contact/hidden',
-                               'sel'   => ($hidden) ? 'active' : '',
+                               'sel'   => $type == 'hidden' ? 'active' : '',
                                'title' => L10n::t('Only show hidden contacts'),
                                'id'    => 'showhidden-tab',
                                'accesskey' => 'h',
                        ],
+                       [
+                               'label' => L10n::t('Groups'),
+                               'url'   => 'group',
+                               'sel'   => '',
+                               'title' => L10n::t('Organize your contact groups'),
+                               'id'    => 'contactgroups-tab',
+                               'accesskey' => 'e',
+                       ],
                ];
 
                $tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl');
@@ -774,6 +751,14 @@ class Contact extends BaseModule
                        $sql_extra .= sprintf(" AND network = '%s' ", DBA::escape($nets));
                }
 
+               switch ($rel) {
+                       case 'followers': $sql_extra .= " AND `rel` IN (1, 3)"; break;
+                       case 'following': $sql_extra .= " AND `rel` IN (2, 3)"; break;
+                       case 'mutuals': $sql_extra .= " AND `rel` = 3"; break;
+               }
+
+               $sql_extra .=  " AND NOT `deleted` ";
+
                $sql_extra2 = ((($sort_type > 0) && ($sort_type <= Model\Contact::FRIEND)) ? sprintf(" AND `rel` = %d ", intval($sort_type)) : '');
 
                $r = q("SELECT COUNT(*) AS `total` FROM `contact`
@@ -802,10 +787,25 @@ class Contact extends BaseModule
                        }
                }
 
+               switch ($rel) {
+                       case 'followers': $header = L10n::t('Followers'); break;
+                       case 'following': $header = L10n::t('Following'); break;
+                       case 'mutuals':   $header = L10n::t('Mutual friends'); break;
+                       default:          $header = L10n::t('Contacts');
+               }
+
+               switch ($type) {
+                       case 'blocked':  $header .= ' - ' . L10n::t('Blocked'); break;
+                       case 'hidden':   $header .= ' - ' . L10n::t('Hidden'); break;
+                       case 'ignored':  $header .= ' - ' . L10n::t('Ignored'); break;
+                       case 'archived': $header .= ' - ' . L10n::t('Archived'); break;
+               }
+
+               $header .= $nets ? ' - ' . ContactSelector::networkToName($nets) : '';
+
                $tpl = Renderer::getMarkupTemplate('contacts-template.tpl');
                $o .= Renderer::replaceMacros($tpl, [
-                       '$baseurl'    => System::baseUrl(),
-                       '$header'     => L10n::t('Contacts') . (($nets) ? ' - ' . ContactSelector::networkToName($nets) : ''),
+                       '$header'     => $header,
                        '$tabs'       => $t,
                        '$total'      => $total,
                        '$search'     => $search_hdr,
@@ -835,12 +835,12 @@ class Contact extends BaseModule
         *
         * Available Pages are 'Status', 'Profile', 'Contacts' and 'Common Friends'
         *
-        * @param App $a
-        * @param array $contact The contact array
-        * @param int $active_tab 1 if tab should be marked as active
+        * @param App   $a
+        * @param array $contact    The contact array
+        * @param int   $active_tab 1 if tab should be marked as active
         *
-        * @return string HTML string of the contact page tabs buttons.
-
+        * @return string HTML string of the contact page tabs buttons.
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
        public static function getTabsHTML($a, $contact, $active_tab)
        {
@@ -933,7 +933,7 @@ class Contact extends BaseModule
                        }
                }
 
-               $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id]);
+               $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id, 'deleted' => false]);
 
                if (!$update) {
                        $o .= self::getTabsHTML($a, $contact, 1);
@@ -957,7 +957,7 @@ class Contact extends BaseModule
 
        private static function getPostsHTML($a, $contact_id)
        {
-               $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id]);
+               $contact = DBA::selectFirst('contact', ['uid', 'url', 'id'], ['id' => $contact_id, 'deleted' => false]);
 
                $o = self::getTabsHTML($a, $contact, 2);
 
@@ -1025,14 +1025,14 @@ class Contact extends BaseModule
                        'alt_text'  => $alt_text,
                        'dir_icon'  => $dir_icon,
                        'thumb'     => ProxyUtils::proxifyUrl($rr['thumb'], false, ProxyUtils::SIZE_THUMB),
-                       'name'      => htmlentities($rr['name']),
-                       'username'  => htmlentities($rr['name']),
+                       'name'      => $rr['name'],
+                       'username'  => $rr['name'],
                        'account_type' => Model\Contact::getAccountType($rr),
                        'sparkle'   => $sparkle,
                        'itemurl'   => defaults($rr, 'addr', $rr['url']),
                        'url'       => $url,
                        'network'   => ContactSelector::networkToName($rr['network'], $rr['url']),
-                       'nick'      => htmlentities($rr['nick']),
+                       'nick'      => $rr['nick'],
                ];
        }