]> git.mxchange.org Git - friendica.git/blob - src/Core/NotificationsManager.php
Merge pull request #7606 from annando/fix-invalid-url
[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' => ['received' => 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' => ['received' => 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' => ['received' => 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          * @param int  $id      When set, only the introduction with this id is displayed
553          *
554          * @return array with
555          *    string 'ident' => Notification identifier
556          *    array 'notifications' => Introductions
557          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
558          * @throws \ImagickException
559          */
560         public function introNotifs($all = false, $start = 0, $limit = 80, $id = 0)
561         {
562                 $ident = 'introductions';
563                 $notifs = [];
564                 $sql_extra = "";
565
566                 if (empty($id)) {
567                         if (!$all) {
568                                 $sql_extra = " AND NOT `ignore` ";
569                         }
570
571                         $sql_extra .= " AND NOT `intro`.`blocked` ";
572                 } else {
573                         $sql_extra = sprintf(" AND `intro`.`id` = %d ", intval($id));
574                 }
575
576                 /// @todo Fetch contact details by "Contact::getDetailsByUrl" instead of queries to contact, fcontact and gcontact
577                 $stmtNotifies = DBA::p(
578                         "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
579                                 `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
580                                 `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
581                                 `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
582                                 `gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
583                                 `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
584                         FROM `intro`
585                                 LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
586                                 LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
587                                 LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
588                         WHERE `intro`.`uid` = ? $sql_extra
589                         LIMIT ?, ?",
590                         $_SESSION['uid'],
591                         $start,
592                         $limit
593                 );
594                 if (DBA::isResult($stmtNotifies)) {
595                         $notifs = $this->formatIntros(DBA::toArray($stmtNotifies));
596                 }
597
598                 $arr = [
599                         'ident' => $ident,
600                         'notifications' => $notifs,
601                 ];
602
603                 return $arr;
604         }
605
606         /**
607          * @brief Format the notification query in an usable array
608          *
609          * @param array $intros The array from the db query
610          * @return array with the introductions
611          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
612          * @throws \ImagickException
613          */
614         private function formatIntros($intros)
615         {
616                 $knowyou = '';
617
618                 $arr = [];
619
620                 foreach ($intros as $it) {
621                         // There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
622                         // We have to distinguish between these two because they use different data.
623                         // Contact suggestions
624                         if ($it['fid']) {
625                                 $return_addr = bin2hex(self::getApp()->user['nickname'] . '@' . self::getApp()->getHostName() . ((self::getApp()->getURLPath()) ? '/' . self::getApp()->getURLPath() : ''));
626
627                                 $intro = [
628                                         'label' => 'friend_suggestion',
629                                         'notify_type' => L10n::t('Friend Suggestion'),
630                                         'intro_id' => $it['intro_id'],
631                                         'madeby' => $it['name'],
632                                         'madeby_url' => $it['url'],
633                                         'madeby_zrl' => Contact::magicLink($it['url']),
634                                         'madeby_addr' => $it['addr'],
635                                         'contact_id' => $it['contact-id'],
636                                         'photo' => (!empty($it['fphoto']) ? ProxyUtils::proxifyUrl($it['fphoto'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
637                                         'name' => $it['fname'],
638                                         'url' => $it['furl'],
639                                         'zrl' => Contact::magicLink($it['furl']),
640                                         'hidden' => $it['hidden'] == 1,
641                                         'post_newfriend' => (intval(PConfig::get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
642                                         'knowyou' => $knowyou,
643                                         'note' => $it['note'],
644                                         'request' => $it['frequest'] . '?addr=' . $return_addr,
645                                 ];
646
647                                 // Normal connection requests
648                         } else {
649                                 $it = $this->getMissingIntroData($it);
650
651                                 if (empty($it['url'])) {
652                                         continue;
653                                 }
654
655                                 // Don't show these data until you are connected. Diaspora is doing the same.
656                                 if ($it['gnetwork'] === Protocol::DIASPORA) {
657                                         $it['glocation'] = "";
658                                         $it['gabout'] = "";
659                                         $it['ggender'] = "";
660                                 }
661                                 $intro = [
662                                         'label' => (($it['network'] !== Protocol::OSTATUS) ? 'friend_request' : 'follower'),
663                                         'notify_type' => (($it['network'] !== Protocol::OSTATUS) ? L10n::t('Friend/Connect Request') : L10n::t('New Follower')),
664                                         'dfrn_id' => $it['issued-id'],
665                                         'uid' => $_SESSION['uid'],
666                                         'intro_id' => $it['intro_id'],
667                                         'contact_id' => $it['contact-id'],
668                                         'photo' => (!empty($it['photo']) ? ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_SMALL) : "images/person-300.jpg"),
669                                         'name' => $it['name'],
670                                         'location' => BBCode::convert($it['glocation'], false),
671                                         'about' => BBCode::convert($it['gabout'], false),
672                                         'keywords' => $it['gkeywords'],
673                                         'gender' => $it['ggender'],
674                                         'hidden' => $it['hidden'] == 1,
675                                         'post_newfriend' => (intval(PConfig::get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
676                                         'url' => $it['url'],
677                                         'zrl' => Contact::magicLink($it['url']),
678                                         'addr' => $it['gaddr'],
679                                         'network' => $it['gnetwork'],
680                                         'knowyou' => $it['knowyou'],
681                                         'note' => $it['note'],
682                                 ];
683                         }
684
685                         $arr[] = $intro;
686                 }
687
688                 return $arr;
689         }
690
691         /**
692          * @brief Check for missing contact data and try to fetch the data from
693          *     from other sources
694          *
695          * @param array $arr The input array with the intro data
696          *
697          * @return array The array with the intro data
698          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
699          */
700         private function getMissingIntroData($arr)
701         {
702                 // If the network and the addr isn't available from the gcontact
703                 // table entry, take the one of the contact table entry
704                 if (empty($arr['gnetwork']) && !empty($arr['network'])) {
705                         $arr['gnetwork'] = $arr['network'];
706                 }
707                 if (empty($arr['gaddr']) && !empty($arr['addr'])) {
708                         $arr['gaddr'] = $arr['addr'];
709                 }
710
711                 // If the network and addr is still not available
712                 // get the missing data data from other sources
713                 if (empty($arr['gnetwork']) || empty($arr['gaddr'])) {
714                         $ret = Contact::getDetailsByURL($arr['url']);
715
716                         if (empty($arr['gnetwork']) && !empty($ret['network'])) {
717                                 $arr['gnetwork'] = $ret['network'];
718                         }
719                         if (empty($arr['gaddr']) && !empty($ret['addr'])) {
720                                 $arr['gaddr'] = $ret['addr'];
721                         }
722                 }
723
724                 return $arr;
725         }
726 }