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