]> git.mxchange.org Git - friendica.git/blob - src/Core/NotificationsManager.php
Merge pull request #6955 from tobiasd/20190331-vier
[friendica.git] / src / Core / NotificationsManager.php
1 <?php
2 /**
3  * @file src/Core/NotificationsManager.php
4  * @brief Methods for read and write notifications from/to database
5  *  or for formatting notifications
6  */
7 namespace Friendica\Core;
8
9 use Friendica\BaseObject;
10 use Friendica\Content\Text\BBCode;
11 use Friendica\Content\Text\HTML;
12 use Friendica\Database\DBA;
13 use Friendica\Model\Contact;
14 use Friendica\Model\Item;
15 use Friendica\Util\DateTimeFormat;
16 use Friendica\Util\Proxy as ProxyUtils;
17 use Friendica\Util\Temporal;
18 use Friendica\Util\XML;
19
20 /**
21  * @brief Methods for read and write notifications from/to database
22  *  or for formatting notifications
23  */
24 class NotificationsManager extends BaseObject
25 {
26         /**
27          * @brief set some extra note properties
28          *
29          * @param array $notes array of note arrays from db
30          * @return array Copy of input array with added properties
31          *
32          * Set some extra properties to note array from db:
33          *  - timestamp as int in default TZ
34          *  - date_rel : relative date string
35          *  - msg_html: message as html string
36          *  - msg_plain: message as plain text string
37          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
38          */
39         private function _set_extra(array $notes)
40         {
41                 $rets = [];
42                 foreach ($notes as $n) {
43                         $local_time = DateTimeFormat::local($n['date']);
44                         $n['timestamp'] = strtotime($local_time);
45                         $n['date_rel'] = Temporal::getRelativeDate($n['date']);
46                         $n['msg_html'] = BBCode::convert($n['msg'], false);
47                         $n['msg_plain'] = explode("\n", trim(HTML::toPlaintext($n['msg_html'], 0)))[0];
48
49                         $rets[] = $n;
50                 }
51                 return $rets;
52         }
53
54         /**
55          * @brief Get all notifications for local_user()
56          *
57          * @param array  $filter optional Array "column name"=>value: filter query by columns values
58          * @param array  $order  optional Array to order by
59          * @param string $limit  optional Query limits
60          *
61          * @return array|bool of results or false on errors
62          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
63          */
64         public function getAll($filter = [], $order = ['date' => 'DESC'], $limit = "")
65         {
66                 $params = [];
67
68                 $params['order'] = $order;
69
70                 if (!empty($limit)) {
71                         $params['limit'] = $limit;
72                 }
73
74                 $dbFilter = array_merge($filter, ['uid' => local_user()]);
75
76                 $stmtNotifies = DBA::select('notify', [], $dbFilter, $params);
77
78                 if (DBA::isResult($stmtNotifies)) {
79                         return $this->_set_extra(DBA::toArray($stmtNotifies));
80                 }
81
82                 return false;
83         }
84
85         /**
86          * @brief Get one note for local_user() by $id value
87          *
88          * @param int $id identity
89          * @return array note values or null if not found
90          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
91          */
92         public function getByID($id)
93         {
94                 $stmtNotify = DBA::selectFirst('notify', [], ['id' => $id, 'uid' => local_user()]);
95                 if (DBA::isResult($stmtNotify)) {
96                         return $this->_set_extra([$stmtNotify])[0];
97                 }
98                 return null;
99         }
100
101         /**
102          * @brief set seen state of $note of local_user()
103          *
104          * @param array $note note array
105          * @param bool  $seen optional true or false, default true
106          * @return bool true on success, false on errors
107          * @throws \Exception
108          */
109         public function setSeen($note, $seen = true)
110         {
111                 return DBA::update('notify', ['seen' => $seen], [
112                         '(`link` = ? OR (`parent` != 0 AND `parent` = ? AND `otype` = ?)) AND `uid` = ?',
113                         $note['link'],
114                         $note['parent'],
115                         $note['otype'],
116                         local_user()
117                 ]);
118         }
119
120         /**
121          * @brief set seen state of all notifications of local_user()
122          *
123          * @param bool $seen optional true or false. default true
124          * @return bool true on success, false on error
125          * @throws \Exception
126          */
127         public function setAllSeen($seen = true)
128         {
129                 return DBA::update('notify', ['seen' => $seen], ['uid' => local_user()]);
130         }
131
132         /**
133          * @brief List of pages for the Notifications TabBar
134          *
135          * @return array with with notifications TabBar data
136          * @throws \Exception
137          */
138         public function getTabs()
139         {
140                 $selected = defaults(self::getApp()->argv, 1, '');
141
142                 $tabs = [
143                         [
144                                 'label' => L10n::t('System'),
145                                 'url'   => 'notifications/system',
146                                 'sel'   => (($selected == 'system') ? 'active' : ''),
147                                 'id'    => 'system-tab',
148                                 'accesskey' => 'y',
149                         ],
150                         [
151                                 'label' => L10n::t('Network'),
152                                 'url'   => 'notifications/network',
153                                 'sel'   => (($selected == 'network') ? 'active' : ''),
154                                 'id'    => 'network-tab',
155                                 'accesskey' => 'w',
156                         ],
157                         [
158                                 'label' => L10n::t('Personal'),
159                                 'url'   => 'notifications/personal',
160                                 'sel'   => (($selected == 'personal') ? 'active' : ''),
161                                 'id'    => 'personal-tab',
162                                 'accesskey' => 'r',
163                         ],
164                         [
165                                 'label' => L10n::t('Home'),
166                                 'url'   => 'notifications/home',
167                                 'sel'   => (($selected == 'home') ? 'active' : ''),
168                                 'id'    => 'home-tab',
169                                 'accesskey' => 'h',
170                         ],
171                         [
172                                 'label' => L10n::t('Introductions'),
173                                 'url'   => 'notifications/intros',
174                                 'sel'   => (($selected == 'intros') ? 'active' : ''),
175                                 'id'    => 'intro-tab',
176                                 'accesskey' => 'i',
177                         ],
178                 ];
179
180                 return $tabs;
181         }
182
183         /**
184          * @brief Format the notification query in an usable array
185          *
186          * @param array  $notifs The array from the db query
187          * @param string $ident  The notifications identifier (e.g. network)
188          * @return array
189          *                       string 'label' => The type of the notification
190          *                       string 'link' => URL to the source
191          *                       string 'image' => The avatar image
192          *                       string 'url' => The profile url of the contact
193          *                       string 'text' => The notification text
194          *                       string 'when' => The date of the notification
195          *                       string 'ago' => T relative date of the notification
196          *                       bool 'seen' => Is the notification marked as "seen"
197          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
198          */
199         private function formatNotifs(array $notifs, $ident = "")
200         {
201                 $arr = [];
202
203                 if (DBA::isResult($notifs)) {
204                         foreach ($notifs as $it) {
205                                 // Because we use different db tables for the notification query
206                                 // we have sometimes $it['unseen'] and sometimes $it['seen].
207                                 // So we will have to transform $it['unseen']
208                                 if (array_key_exists('unseen', $it)) {
209                                         $it['seen'] = ($it['unseen'] > 0 ? false : true);
210                                 }
211
212                                 // For feed items we use the user's contact, since the avatar is mostly self choosen.
213                                 if (!empty($it['network']) && $it['network'] == Protocol::FEED) {
214                                         $it['author-avatar'] = $it['contact-avatar'];
215                                 }
216
217                                 // Depending on the identifier of the notification we need to use different defaults
218                                 switch ($ident) {
219                                         case 'system':
220                                                 $default_item_label = 'notify';
221                                                 $default_item_link = System::baseUrl(true) . '/notify/view/' . $it['id'];
222                                                 $default_item_image = ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_MICRO);
223                                                 $default_item_url = $it['url'];
224                                                 $default_item_text = strip_tags(BBCode::convert($it['msg']));
225                                                 $default_item_when = DateTimeFormat::local($it['date'], 'r');
226                                                 $default_item_ago = Temporal::getRelativeDate($it['date']);
227                                                 break;
228
229                                         case 'home':
230                                                 $default_item_label = 'comment';
231                                                 $default_item_link = System::baseUrl(true) . '/display/' . $it['parent-guid'];
232                                                 $default_item_image = ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO);
233                                                 $default_item_url = $it['author-link'];
234                                                 $default_item_text = L10n::t("%s commented on %s's post", $it['author-name'], $it['parent-author-name']);
235                                                 $default_item_when = DateTimeFormat::local($it['created'], 'r');
236                                                 $default_item_ago = Temporal::getRelativeDate($it['created']);
237                                                 break;
238
239                                         default:
240                                                 $default_item_label = (($it['id'] == $it['parent']) ? 'post' : 'comment');
241                                                 $default_item_link = System::baseUrl(true) . '/display/' . $it['parent-guid'];
242                                                 $default_item_image = ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO);
243                                                 $default_item_url = $it['author-link'];
244                                                 $default_item_text = (($it['id'] == $it['parent'])
245                                                                         ? L10n::t("%s created a new post", $it['author-name'])
246                                                                         : L10n::t("%s commented on %s's post", $it['author-name'], $it['parent-author-name']));
247                                                 $default_item_when = DateTimeFormat::local($it['created'], 'r');
248                                                 $default_item_ago = Temporal::getRelativeDate($it['created']);
249                                 }
250
251                                 // Transform the different types of notification in an usable array
252                                 switch ($it['verb']) {
253                                         case ACTIVITY_LIKE:
254                                                 $notif = [
255                                                         'label' => 'like',
256                                                         'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
257                                                         'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
258                                                         'url' => $it['author-link'],
259                                                         'text' => L10n::t("%s liked %s's post", $it['author-name'], $it['parent-author-name']),
260                                                         'when' => $default_item_when,
261                                                         'ago' => $default_item_ago,
262                                                         'seen' => $it['seen']
263                                                 ];
264                                                 break;
265
266                                         case ACTIVITY_DISLIKE:
267                                                 $notif = [
268                                                         'label' => 'dislike',
269                                                         'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
270                                                         'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
271                                                         'url' => $it['author-link'],
272                                                         'text' => L10n::t("%s disliked %s's post", $it['author-name'], $it['parent-author-name']),
273                                                         'when' => $default_item_when,
274                                                         'ago' => $default_item_ago,
275                                                         'seen' => $it['seen']
276                                                 ];
277                                                 break;
278
279                                         case ACTIVITY_ATTEND:
280                                                 $notif = [
281                                                         'label' => 'attend',
282                                                         'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
283                                                         'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
284                                                         'url' => $it['author-link'],
285                                                         'text' => L10n::t("%s is attending %s's event", $it['author-name'], $it['parent-author-name']),
286                                                         'when' => $default_item_when,
287                                                         'ago' => $default_item_ago,
288                                                         'seen' => $it['seen']
289                                                 ];
290                                                 break;
291
292                                         case ACTIVITY_ATTENDNO:
293                                                 $notif = [
294                                                         'label' => 'attendno',
295                                                         'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
296                                                         'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
297                                                         'url' => $it['author-link'],
298                                                         'text' => L10n::t("%s is not attending %s's event", $it['author-name'], $it['parent-author-name']),
299                                                         'when' => $default_item_when,
300                                                         'ago' => $default_item_ago,
301                                                         'seen' => $it['seen']
302                                                 ];
303                                                 break;
304
305                                         case ACTIVITY_ATTENDMAYBE:
306                                                 $notif = [
307                                                         'label' => 'attendmaybe',
308                                                         'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
309                                                         'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
310                                                         'url' => $it['author-link'],
311                                                         'text' => L10n::t("%s may attend %s's event", $it['author-name'], $it['parent-author-name']),
312                                                         'when' => $default_item_when,
313                                                         'ago' => $default_item_ago,
314                                                         'seen' => $it['seen']
315                                                 ];
316                                                 break;
317
318                                         case ACTIVITY_FRIEND:
319                                                 if (!isset($it['object'])) {
320                                                         $notif = [
321                                                                 'label' => 'friend',
322                                                                 'link' => $default_item_link,
323                                                                 'image' => $default_item_image,
324                                                                 'url' => $default_item_url,
325                                                                 'text' => $default_item_text,
326                                                                 'when' => $default_item_when,
327                                                                 'ago' => $default_item_ago,
328                                                                 'seen' => $it['seen']
329                                                         ];
330                                                         break;
331                                                 }
332                                                 /// @todo Check if this part here is used at all
333                                                 Logger::log('Complete data: ' . json_encode($it) . ' - ' . System::callstack(20), Logger::DEBUG);
334
335                                                 $xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
336                                                 $obj = XML::parseString($xmlhead . $it['object']);
337                                                 $it['fname'] = $obj->title;
338
339                                                 $notif = [
340                                                         'label' => 'friend',
341                                                         'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
342                                                         'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
343                                                         'url' => $it['author-link'],
344                                                         'text' => L10n::t("%s is now friends with %s", $it['author-name'], $it['fname']),
345                                                         'when' => $default_item_when,
346                                                         'ago' => $default_item_ago,
347                                                         'seen' => $it['seen']
348                                                 ];
349                                                 break;
350
351                                         default:
352                                                 $notif = [
353                                                         'label' => $default_item_label,
354                                                         'link' => $default_item_link,
355                                                         'image' => $default_item_image,
356                                                         'url' => $default_item_url,
357                                                         'text' => $default_item_text,
358                                                         'when' => $default_item_when,
359                                                         'ago' => $default_item_ago,
360                                                         'seen' => $it['seen']
361                                                 ];
362                                 }
363
364                                 $arr[] = $notif;
365                         }
366                 }
367
368                 return $arr;
369         }
370
371         /**
372          * @brief Get network notifications
373          *
374          * @param int|string $seen    If 0 only include notifications into the query
375          *                            which aren't marked as "seen"
376          * @param int        $start   Start the query at this point
377          * @param int        $limit   Maximum number of query results
378          *
379          * @return array with
380          *    string 'ident' => Notification identifier
381          *    array 'notifications' => Network notifications
382          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
383          */
384         public function networkNotifs($seen = 0, $start = 0, $limit = 80)
385         {
386                 $ident = 'network';
387                 $notifs = [];
388
389                 $condition = ['wall' => false, 'uid' => local_user()];
390
391                 if ($seen === 0) {
392                         $condition['unseen'] = true;
393                 }
394
395                 $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
396                         'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
397                 $params = ['order' => ['created' => true], 'limit' => [$start, $limit]];
398
399                 $items = Item::selectForUser(local_user(), $fields, $condition, $params);
400
401                 if (DBA::isResult($items)) {
402                         $notifs = $this->formatNotifs(Item::inArray($items), $ident);
403                 }
404
405                 $arr = [
406                         'notifications' => $notifs,
407                         'ident' => $ident,
408                 ];
409
410                 return $arr;
411         }
412
413         /**
414          * @brief Get system notifications
415          *
416          * @param int|string $seen    If 0 only include notifications into the query
417          *                            which aren't marked as "seen"
418          * @param int        $start   Start the query at this point
419          * @param int        $limit   Maximum number of query results
420          *
421          * @return array with
422          *    string 'ident' => Notification identifier
423          *    array 'notifications' => System notifications
424          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
425          */
426         public function systemNotifs($seen = 0, $start = 0, $limit = 80)
427         {
428                 $ident = 'system';
429                 $notifs = [];
430                 $sql_seen = "";
431
432                 $filter = ['uid' => local_user()];
433                 if ($seen === 0) {
434                         $filter['seen'] = false;
435                 }
436
437                 $params = [];
438                 $params['order'] = ['date' => 'DESC'];
439                 $params['limit'] = [$start, $limit];
440
441                 $stmtNotifies = DBA::select('notify',
442                         ['id', 'url', 'photo', 'msg', 'date', 'seen', 'verb'],
443                         $filter,
444                         $params);
445
446                 if (DBA::isResult($stmtNotifies)) {
447                         $notifs = $this->formatNotifs(DBA::toArray($stmtNotifies), $ident);
448                 }
449
450                 $arr = [
451                         'notifications' => $notifs,
452                         'ident' => $ident,
453                 ];
454
455                 return $arr;
456         }
457
458         /**
459          * @brief Get personal notifications
460          *
461          * @param int|string $seen    If 0 only include notifications into the query
462          *                            which aren't marked as "seen"
463          * @param int        $start   Start the query at this point
464          * @param int        $limit   Maximum number of query results
465          *
466          * @return array with
467          *    string 'ident' => Notification identifier
468          *    array 'notifications' => Personal notifications
469          * @throws \Exception
470          */
471         public function personalNotifs($seen = 0, $start = 0, $limit = 80)
472         {
473                 $ident = 'personal';
474                 $notifs = [];
475
476                 $myurl = str_replace('http://', '', self::getApp()->contact['nurl']);
477                 $diasp_url = str_replace('/profile/', '/u/', $myurl);
478
479                 $condition = ["NOT `wall` AND `uid` = ? AND (`item`.`author-id` = ? OR `item`.`tag` REGEXP ? OR `item`.`tag` REGEXP ?)",
480                         local_user(), public_contact(), $myurl . '\\]', $diasp_url . '\\]'];
481
482                 if ($seen === 0) {
483                         $condition[0] .= " AND `unseen`";
484                 }
485
486                 $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
487                         'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
488                 $params = ['order' => ['created' => true], 'limit' => [$start, $limit]];
489
490                 $items = Item::selectForUser(local_user(), $fields, $condition, $params);
491
492                 if (DBA::isResult($items)) {
493                         $notifs = $this->formatNotifs(Item::inArray($items), $ident);
494                 }
495
496                 $arr = [
497                         'notifications' => $notifs,
498                         'ident' => $ident,
499                 ];
500
501                 return $arr;
502         }
503
504         /**
505          * @brief Get home notifications
506          *
507          * @param int|string $seen    If 0 only include notifications into the query
508          *                            which aren't marked as "seen"
509          * @param int        $start   Start the query at this point
510          * @param int        $limit   Maximum number of query results
511          *
512          * @return array with
513          *    string 'ident' => Notification identifier
514          *    array 'notifications' => Home notifications
515          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
516          */
517         public function homeNotifs($seen = 0, $start = 0, $limit = 80)
518         {
519                 $ident = 'home';
520                 $notifs = [];
521
522                 $condition = ['wall' => true, 'uid' => local_user()];
523
524                 if ($seen === 0) {
525                         $condition['unseen'] = true;
526                 }
527
528                 $fields = ['id', 'parent', 'verb', 'author-name', 'unseen', 'author-link', 'author-avatar', 'contact-avatar',
529                         'network', 'created', 'object', 'parent-author-name', 'parent-author-link', 'parent-guid'];
530                 $params = ['order' => ['created' => true], 'limit' => [$start, $limit]];
531                 $items = Item::selectForUser(local_user(), $fields, $condition, $params);
532
533                 if (DBA::isResult($items)) {
534                         $notifs = $this->formatNotifs(Item::inArray($items), $ident);
535                 }
536
537                 $arr = [
538                         'notifications' => $notifs,
539                         'ident' => $ident,
540                 ];
541
542                 return $arr;
543         }
544
545         /**
546          * @brief Get introductions
547          *
548          * @param bool $all     If false only include introductions into the query
549          *                      which aren't marked as ignored
550          * @param int  $start   Start the query at this point
551          * @param int  $limit   Maximum number of query results
552          *
553          * @return array with
554          *    string 'ident' => Notification identifier
555          *    array 'notifications' => Introductions
556          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
557          * @throws \ImagickException
558          */
559         public function introNotifs($all = false, $start = 0, $limit = 80)
560         {
561                 $ident = 'introductions';
562                 $notifs = [];
563                 $sql_extra = "";
564
565                 if (!$all) {
566                         $sql_extra = " AND NOT `ignore` ";
567                 }
568
569                 /// @todo Fetch contact details by "Contact::getDetailsByUrl" instead of queries to contact, fcontact and gcontact
570                 $stmtNotifies = DBA::p(
571                         "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
572                                 `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
573                                 `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
574                                 `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
575                                 `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
576                                 `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
577                         FROM `intro`
578                                 LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
579                                 LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
580                                 LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
581                         WHERE `intro`.`uid` = ? $sql_extra AND `intro`.`blocked` = 0
582                         LIMIT ?, ?",
583                         $_SESSION['uid'],
584                         $start,
585                         $limit
586                 );
587                 if (DBA::isResult($stmtNotifies)) {
588                         $notifs = $this->formatIntros(DBA::toArray($stmtNotifies));
589                 }
590
591                 $arr = [
592                         'ident' => $ident,
593                         'notifications' => $notifs,
594                 ];
595
596                 return $arr;
597         }
598
599         /**
600          * @brief Format the notification query in an usable array
601          *
602          * @param array $intros The array from the db query
603          * @return array with the introductions
604          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
605          * @throws \ImagickException
606          */
607         private function formatIntros($intros)
608         {
609                 $knowyou = '';
610
611                 $arr = [];
612
613                 foreach ($intros as $it) {
614                         // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
615                         // We have to distinguish between these two because they use different data.
616                         // Contact suggestions
617                         if ($it['fid']) {
618                                 $return_addr = bin2hex(self::getApp()->user['nickname'] . '@' . self::getApp()->getHostName() . ((self::getApp()->getURLPath()) ? '/' . self::getApp()->getURLPath() : ''));
619
620                                 $intro = [
621                                         'label' => 'friend_suggestion',
622                                         'notify_type' => L10n::t('Friend Suggestion'),
623                                         'intro_id' => $it['intro_id'],
624                                         'madeby' => $it['name'],
625                                         'madeby_url' => $it['url'],
626                                         'madeby_zrl' => Contact::magicLink($it['url']),
627                                         'madeby_addr' => $it['addr'],
628                                         'contact_id' => $it['contact-id'],
629                                         'photo' => (!empty($it['fphoto']) ? ProxyUtils::proxifyUrl($it['fphoto'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
630                                         'name' => $it['fname'],
631                                         'url' => $it['furl'],
632                                         'zrl' => Contact::magicLink($it['furl']),
633                                         'hidden' => $it['hidden'] == 1,
634                                         'post_newfriend' => (intval(PConfig::get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
635                                         'knowyou' => $knowyou,
636                                         'note' => $it['note'],
637                                         'request' => $it['frequest'] . '?addr=' . $return_addr,
638                                 ];
639
640                                 // Normal connection requests
641                         } else {
642                                 $it = $this->getMissingIntroData($it);
643
644                                 if (empty($it['url'])) {
645                                         continue;
646                                 }
647
648                                 // Don't show these data until you are connected. Diaspora is doing the same.
649                                 if ($it['gnetwork'] === Protocol::DIASPORA) {
650                                         $it['glocation'] = "";
651                                         $it['gabout'] = "";
652                                         $it['ggender'] = "";
653                                 }
654                                 $intro = [
655                                         'label' => (($it['network'] !== Protocol::OSTATUS) ? 'friend_request' : 'follower'),
656                                         'notify_type' => (($it['network'] !== Protocol::OSTATUS) ? L10n::t('Friend/Connect Request') : L10n::t('New Follower')),
657                                         'dfrn_id' => $it['issued-id'],
658                                         'uid' => $_SESSION['uid'],
659                                         'intro_id' => $it['intro_id'],
660                                         'contact_id' => $it['contact-id'],
661                                         'photo' => (!empty($it['photo']) ? ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
662                                         'name' => $it['name'],
663                                         'location' => BBCode::convert($it['glocation'], false),
664                                         'about' => BBCode::convert($it['gabout'], false),
665                                         'keywords' => $it['gkeywords'],
666                                         'gender' => $it['ggender'],
667                                         'hidden' => $it['hidden'] == 1,
668                                         'post_newfriend' => (intval(PConfig::get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
669                                         'url' => $it['url'],
670                                         'zrl' => Contact::magicLink($it['url']),
671                                         'addr' => $it['gaddr'],
672                                         'network' => $it['gnetwork'],
673                                         'knowyou' => $it['knowyou'],
674                                         'note' => $it['note'],
675                                 ];
676                         }
677
678                         $arr[] = $intro;
679                 }
680
681                 return $arr;
682         }
683
684         /**
685          * @brief Check for missing contact data and try to fetch the data from
686          *     from other sources
687          *
688          * @param array $arr The input array with the intro data
689          *
690          * @return array The array with the intro data
691          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
692          */
693         private function getMissingIntroData($arr)
694         {
695                 // If the network and the addr isn't available from the gcontact
696                 // table entry, take the one of the contact table entry
697                 if (empty($arr['gnetwork']) && !empty($arr['network'])) {
698                         $arr['gnetwork'] = $arr['network'];
699                 }
700                 if (empty($arr['gaddr']) && !empty($arr['addr'])) {
701                         $arr['gaddr'] = $arr['addr'];
702                 }
703
704                 // If the network and addr is still not available
705                 // get the missing data data from other sources
706                 if (empty($arr['gnetwork']) || empty($arr['gaddr'])) {
707                         $ret = Contact::getDetailsByURL($arr['url']);
708
709                         if (empty($arr['gnetwork']) && !empty($ret['network'])) {
710                                 $arr['gnetwork'] = $ret['network'];
711                         }
712                         if (empty($arr['gaddr']) && !empty($ret['addr'])) {
713                                 $arr['gaddr'] = $ret['addr'];
714                         }
715                 }
716
717                 return $arr;
718         }
719 }