]> git.mxchange.org Git - friendica.git/blob - include/Contact.php
Fetching new queue tasks in a bulk to increase speed
[friendica.git] / include / Contact.php
1 <?php
2
3 use Friendica\App;
4 use Friendica\Network\Probe;
5
6 // Included here for completeness, but this is a very dangerous operation.
7 // It is the caller's responsibility to confirm the requestor's intent and
8 // authorisation to do this.
9
10 function user_remove($uid) {
11         if(! $uid)
12                 return;
13         logger('Removing user: ' . $uid);
14
15         $r = q("select * from user where uid = %d limit 1", intval($uid));
16
17         call_hooks('remove_user',$r[0]);
18
19         // save username (actually the nickname as it is guaranteed
20         // unique), so it cannot be re-registered in the future.
21
22         q("insert into userd ( username ) values ( '%s' )",
23                 $r[0]['nickname']
24         );
25
26         // The user and related data will be deleted in "cron_expire_and_remove_users" (cronjobs.php)
27         q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
28         proc_run(PRIORITY_HIGH, "include/notifier.php", "removeme", $uid);
29
30         // Send an update to the directory
31         proc_run(PRIORITY_LOW, "include/directory.php", $r[0]['url']);
32
33         if($uid == local_user()) {
34                 unset($_SESSION['authenticated']);
35                 unset($_SESSION['uid']);
36                 goaway(App::get_baseurl());
37         }
38 }
39
40
41 function contact_remove($id) {
42
43         // We want just to make sure that we don't delete our "self" contact
44         $r = q("SELECT `uid` FROM `contact` WHERE `id` = %d AND NOT `self` LIMIT 1",
45                 intval($id)
46         );
47         if (!dbm::is_result($r) || !intval($r[0]['uid'])) {
48                 return;
49         }
50
51         $archive = get_pconfig($r[0]['uid'], 'system','archive_removed_contacts');
52         if ($archive) {
53                 q("update contact set `archive` = 1, `network` = 'none', `writable` = 0 where id = %d",
54                         intval($id)
55                 );
56                 return;
57         }
58
59         q("DELETE FROM `contact` WHERE `id` = %d", intval($id));
60
61         // Delete the rest in the background
62         proc_run(PRIORITY_LOW, 'include/remove_contact.php', $id);
63 }
64
65
66 // sends an unfriend message. Does not remove the contact
67
68 function terminate_friendship($user,$self,$contact) {
69
70         /// @TODO Get rid of this, include/datetime.php should care about it by itself
71         $a = get_app();
72
73         require_once 'include/datetime.php';
74
75         if ($contact['network'] === NETWORK_OSTATUS) {
76
77                 require_once 'include/ostatus.php';
78
79                 // create an unfollow slap
80                 $item = array();
81                 $item['verb'] = NAMESPACE_OSTATUS."/unfollow";
82                 $item['follow'] = $contact["url"];
83                 $slap = ostatus::salmon($item, $user);
84
85                 if ((x($contact,'notify')) && (strlen($contact['notify']))) {
86                         require_once 'include/salmon.php';
87                         slapper($user,$contact['notify'],$slap);
88                 }
89         } elseif ($contact['network'] === NETWORK_DIASPORA) {
90                 require_once 'include/diaspora.php';
91                 Diaspora::send_unshare($user,$contact);
92         } elseif ($contact['network'] === NETWORK_DFRN) {
93                 require_once 'include/dfrn.php';
94                 dfrn::deliver($user,$contact,'placeholder', 1);
95         }
96
97 }
98
99
100 // Contact has refused to recognise us as a friend. We will start a countdown.
101 // If they still don't recognise us in 32 days, the relationship is over,
102 // and we won't waste any more time trying to communicate with them.
103 // This provides for the possibility that their database is temporarily messed
104 // up or some other transient event and that there's a possibility we could recover from it.
105
106 function mark_for_death($contact) {
107
108         if($contact['archive'])
109                 return;
110
111         if ($contact['term-date'] <= NULL_DATE) {
112                 q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d",
113                                 dbesc(datetime_convert()),
114                                 intval($contact['id'])
115                 );
116
117                 if ($contact['url'] != '') {
118                         q("UPDATE `contact` SET `term-date` = '%s'
119                                 WHERE `nurl` = '%s' AND `term-date` <= '1000-00-00'",
120                                         dbesc(datetime_convert()),
121                                         dbesc(normalise_link($contact['url']))
122                         );
123                 }
124         } else {
125
126                 /// @todo
127                 /// We really should send a notification to the owner after 2-3 weeks
128                 /// so they won't be surprised when the contact vanishes and can take
129                 /// remedial action if this was a serious mistake or glitch
130
131                 /// @todo
132                 /// Check for contact vitality via probing
133
134                 $expiry = $contact['term-date'] . ' + 32 days ';
135                 if(datetime_convert() > datetime_convert('UTC','UTC',$expiry)) {
136
137                         // relationship is really truly dead.
138                         // archive them rather than delete
139                         // though if the owner tries to unarchive them we'll start the whole process over again
140
141                         q("UPDATE `contact` SET `archive` = 1 WHERE `id` = %d",
142                                 intval($contact['id'])
143                         );
144
145                         if ($contact['url'] != '') {
146                                 q("UPDATE `contact` SET `archive` = 1 WHERE `nurl` = '%s'",
147                                         dbesc(normalise_link($contact['url']))
148                                 );
149                         }
150                 }
151         }
152
153 }
154
155 function unmark_for_death($contact) {
156
157         $r = q("SELECT `term-date` FROM `contact` WHERE `id` = %d AND `term-date` > '%s'",
158                 intval($contact['id']),
159                 dbesc('1000-00-00 00:00:00')
160         );
161
162         // We don't need to update, we never marked this contact as dead
163         if (!dbm::is_result($r)) {
164                 return;
165         }
166
167         // It's a miracle. Our dead contact has inexplicably come back to life.
168         q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d",
169                 dbesc(NULL_DATE),
170                 intval($contact['id'])
171         );
172
173         if ($contact['url'] != '') {
174                 q("UPDATE `contact` SET `term-date` = '%s' WHERE `nurl` = '%s'",
175                         dbesc(NULL_DATE),
176                         dbesc(normalise_link($contact['url']))
177                 );
178         }
179 }
180
181 /**
182  * @brief Get contact data for a given profile link
183  *
184  * The function looks at several places (contact table and gcontact table) for the contact
185  * It caches its result for the same script execution to prevent duplicate calls
186  *
187  * @param string $url The profile link
188  * @param int $uid User id
189  * @param array $default If not data was found take this data as default value
190  *
191  * @return array Contact data
192  */
193 function get_contact_details_by_url($url, $uid = -1, $default = array()) {
194         static $cache = array();
195
196         if ($url == '') {
197                 return $default;
198         }
199
200         if ($uid == -1) {
201                 $uid = local_user();
202         }
203
204         if (isset($cache[$url][$uid])) {
205                 return $cache[$url][$uid];
206         }
207
208         // Fetch contact data from the contact table for the given user
209         $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
210                         `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
211                 FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
212                         dbesc(normalise_link($url)), intval($uid));
213
214         // Fetch the data from the contact table with "uid=0" (which is filled automatically)
215         if (!dbm::is_result($r))
216                 $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
217                         `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
218                         FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
219                                 dbesc(normalise_link($url)));
220
221         // Fetch the data from the gcontact table
222         if (!dbm::is_result($r))
223                 $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
224                         `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
225                         FROM `gcontact` WHERE `nurl` = '%s'",
226                                 dbesc(normalise_link($url)));
227
228         if (dbm::is_result($r)) {
229                 // If there is more than one entry we filter out the connector networks
230                 if (count($r) > 1) {
231                         foreach ($r AS $id => $result) {
232                                 if ($result["network"] == NETWORK_STATUSNET) {
233                                         unset($r[$id]);
234                                 }
235                         }
236                 }
237
238                 $profile = array_shift($r);
239
240                 // "bd" always contains the upcoming birthday of a contact.
241                 // "birthday" might contain the birthday including the year of birth.
242                 if ($profile["birthday"] > '0001-01-01') {
243                         $bd_timestamp = strtotime($profile["birthday"]);
244                         $month = date("m", $bd_timestamp);
245                         $day = date("d", $bd_timestamp);
246
247                         $current_timestamp = time();
248                         $current_year = date("Y", $current_timestamp);
249                         $current_month = date("m", $current_timestamp);
250                         $current_day = date("d", $current_timestamp);
251
252                         $profile["bd"] = $current_year."-".$month."-".$day;
253                         $current = $current_year."-".$current_month."-".$current_day;
254
255                         if ($profile["bd"] < $current) {
256                                 $profile["bd"] = (++$current_year)."-".$month."-".$day;
257                         }
258                 } else {
259                         $profile["bd"] = '0001-01-01';
260                 }
261         } else {
262                 $profile = $default;
263         }
264
265         if (($profile["photo"] == "") && isset($default["photo"])) {
266                 $profile["photo"] = $default["photo"];
267         }
268
269         if (($profile["name"] == "") && isset($default["name"])) {
270                 $profile["name"] = $default["name"];
271         }
272
273         if (($profile["network"] == "") && isset($default["network"])) {
274                 $profile["network"] = $default["network"];
275         }
276
277         if (($profile["thumb"] == "") && isset($profile["photo"])) {
278                 $profile["thumb"] = $profile["photo"];
279         }
280
281         if (($profile["micro"] == "") && isset($profile["thumb"])) {
282                 $profile["micro"] = $profile["thumb"];
283         }
284
285         if ((($profile["addr"] == "") || ($profile["name"] == "")) && ($profile["gid"] != 0) &&
286                 in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
287                 proc_run(PRIORITY_LOW, "include/update_gcontact.php", $profile["gid"]);
288         }
289
290         // Show contact details of Diaspora contacts only if connected
291         if (($profile["cid"] == 0) && ($profile["network"] == NETWORK_DIASPORA)) {
292                 $profile["location"] = "";
293                 $profile["about"] = "";
294                 $profile["gender"] = "";
295                 $profile["birthday"] = '0001-01-01';
296         }
297
298         $cache[$url][$uid] = $profile;
299
300         return $profile;
301 }
302
303 /**
304  * @brief Get contact data for a given address
305  *
306  * The function looks at several places (contact table and gcontact table) for the contact
307  *
308  * @param string $addr The profile link
309  * @param int $uid User id
310  *
311  * @return array Contact data
312  */
313 function get_contact_details_by_addr($addr, $uid = -1) {
314         static $cache = array();
315
316         if ($addr == '') {
317                 return array();
318         }
319
320         if ($uid == -1) {
321                 $uid = local_user();
322         }
323
324         // Fetch contact data from the contact table for the given user
325         $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
326                         `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
327                 FROM `contact` WHERE `addr` = '%s' AND `uid` = %d",
328                         dbesc($addr), intval($uid));
329
330         // Fetch the data from the contact table with "uid=0" (which is filled automatically)
331         if (!dbm::is_result($r))
332                 $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
333                         `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
334                         FROM `contact` WHERE `addr` = '%s' AND `uid` = 0",
335                                 dbesc($addr));
336
337         // Fetch the data from the gcontact table
338         if (!dbm::is_result($r))
339                 $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
340                         `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
341                         FROM `gcontact` WHERE `addr` = '%s'",
342                                 dbesc($addr));
343
344         if (!dbm::is_result($r)) {
345                 $data = Probe::uri($addr);
346
347                 $profile = get_contact_details_by_url($data['url'], $uid);
348         } else {
349                 $profile = $r[0];
350         }
351
352         return $profile;
353 }
354
355 if (! function_exists('contact_photo_menu')) {
356 function contact_photo_menu($contact, $uid = 0)
357 {
358         $a = get_app();
359
360         $contact_url = '';
361         $pm_url = '';
362         $status_link = '';
363         $photos_link = '';
364         $posts_link = '';
365         $contact_drop_link = '';
366         $poke_link = '';
367
368         if ($uid == 0) {
369                 $uid = local_user();
370         }
371
372         if ($contact['uid'] != $uid) {
373                 if ($uid == 0) {
374                         $profile_link = zrl($contact['url']);
375                         $menu = Array('profile' => array(t('View Profile'), $profile_link, true));
376
377                         return $menu;
378                 }
379
380                 $r = q("SELECT * FROM `contact` WHERE `nurl` = '%s' AND `network` = '%s' AND `uid` = %d",
381                         dbesc($contact['nurl']), dbesc($contact['network']), intval($uid));
382                 if ($r) {
383                         return contact_photo_menu($r[0], $uid);
384                 } else {
385                         $profile_link = zrl($contact['url']);
386                         $connlnk = 'follow/?url='.$contact['url'];
387                         $menu = array(
388                                 'profile' => array(t('View Profile'), $profile_link, true),
389                                 'follow' => array(t('Connect/Follow'), $connlnk, true)
390                         );
391
392                         return $menu;
393                 }
394         }
395
396         $sparkle = false;
397         if ($contact['network'] === NETWORK_DFRN) {
398                 $sparkle = true;
399                 $profile_link = App::get_baseurl() . '/redir/' . $contact['id'];
400         } else {
401                 $profile_link = $contact['url'];
402         }
403
404         if ($profile_link === 'mailbox') {
405                 $profile_link = '';
406         }
407
408         if ($sparkle) {
409                 $status_link = $profile_link . '?url=status';
410                 $photos_link = $profile_link . '?url=photos';
411                 $profile_link = $profile_link . '?url=profile';
412         }
413
414         if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
415                 $pm_url = App::get_baseurl() . '/message/new/' . $contact['id'];
416         }
417
418         if ($contact['network'] == NETWORK_DFRN) {
419                 $poke_link = App::get_baseurl() . '/poke/?f=&c=' . $contact['id'];
420         }
421
422         $contact_url = App::get_baseurl() . '/contacts/' . $contact['id'];
423
424         $posts_link = App::get_baseurl() . '/contacts/' . $contact['id'] . '/posts';
425         $contact_drop_link = App::get_baseurl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
426
427         /**
428          * menu array:
429          * "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
430          */
431         $menu = array(
432                 'status' => array(t("View Status"), $status_link, true),
433                 'profile' => array(t("View Profile"), $profile_link, true),
434                 'photos' => array(t("View Photos"), $photos_link, true),
435                 'network' => array(t("Network Posts"), $posts_link, false),
436                 'edit' => array(t("View Contact"), $contact_url, false),
437                 'drop' => array(t("Drop Contact"), $contact_drop_link, false),
438                 'pm' => array(t("Send PM"), $pm_url, false),
439                 'poke' => array(t("Poke"), $poke_link, false),
440         );
441
442
443         $args = array('contact' => $contact, 'menu' => &$menu);
444
445         call_hooks('contact_photo_menu', $args);
446
447         $menucondensed = array();
448
449         foreach ($menu AS $menuname => $menuitem) {
450                 if ($menuitem[1] != '') {
451                         $menucondensed[$menuname] = $menuitem;
452                 }
453         }
454
455         return $menucondensed;
456 }}
457
458
459 function random_profile() {
460         $r = q("SELECT `url` FROM `gcontact` WHERE `network` = '%s'
461                                 AND `last_contact` >= `last_failure`
462                                 AND `updated` > UTC_TIMESTAMP - INTERVAL 1 MONTH
463                         ORDER BY rand() LIMIT 1",
464                 dbesc(NETWORK_DFRN));
465
466         if (dbm::is_result($r))
467                 return dirname($r[0]['url']);
468         return '';
469 }
470
471
472 function contacts_not_grouped($uid,$start = 0,$count = 0) {
473
474         if(! $count) {
475                 $r = q("select count(*) as total from contact where uid = %d and self = 0 and id not in (select distinct(`contact-id`) from group_member where uid = %d) ",
476                         intval($uid),
477                         intval($uid)
478                 );
479
480                 return $r;
481
482
483         }
484
485         $r = q("select * from contact where uid = %d and self = 0 and id not in (select distinct(`contact-id`) from group_member where uid = %d) and blocked = 0 and pending = 0 limit %d, %d",
486                 intval($uid),
487                 intval($uid),
488                 intval($start),
489                 intval($count)
490         );
491
492         return $r;
493 }
494
495 /**
496  * @brief Fetch the contact id for a given url and user
497  *
498  * First lookup in the contact table to find a record matching either `url`, `nurl`,
499  * `addr` or `alias`.
500  *
501  * If there's no record and we aren't looking for a public contact, we quit.
502  * If there's one, we check that it isn't time to update the picture else we
503  * directly return the found contact id.
504  *
505  * Second, we probe the provided $url wether it's http://server.tld/profile or
506  * nick@server.tld. We quit if we can't get any info back.
507  *
508  * Third, we create the contact record if it doesn't exist
509  *
510  * Fourth, we update the existing record with the new data (avatar, alias, nick)
511  * if there's any updates
512  *
513  * @param string $url Contact URL
514  * @param integer $uid The user id for the contact (0 = public contact)
515  * @param boolean $no_update Don't update the contact
516  *
517  * @return integer Contact ID
518  */
519 function get_contact($url, $uid = 0, $no_update = false) {
520         logger("Get contact data for url ".$url." and user ".$uid." - ".App::callstack(), LOGGER_DEBUG);;
521
522         $data = array();
523         $contact_id = 0;
524
525         if ($url == '') {
526                 return 0;
527         }
528
529         // We first try the nurl (http://server.tld/nick), most common case
530         $contacts = q("SELECT `id`, `avatar-date` FROM `contact`
531                                         WHERE `nurl` = '%s'
532                                         AND `uid` = %d",
533                         dbesc(normalise_link($url)),
534                         intval($uid));
535
536
537         // Then the addr (nick@server.tld)
538         if (! dbm::is_result($contacts)) {
539                 $contacts = q("SELECT `id`, `avatar-date` FROM `contact`
540                                         WHERE `addr` = '%s'
541                                         AND `uid` = %d",
542                         dbesc($url),
543                         intval($uid));
544         }
545
546         // Then the alias (which could be anything)
547         if (! dbm::is_result($contacts)) {
548                 $contacts = q("SELECT `id`, `avatar-date` FROM `contact`
549                                         WHERE `alias` IN ('%s', '%s')
550                                         AND `uid` = %d",
551                         dbesc($url),
552                         dbesc(normalise_link($url)),
553                         intval($uid));
554         }
555
556         if (dbm::is_result($contacts)) {
557                 $contact_id = $contacts[0]["id"];
558
559                 // Update the contact every 7 days
560                 $update_photo = ($contacts[0]['avatar-date'] < datetime_convert('','','now -7 days'));
561
562                 if (!$update_photo || $no_update) {
563                         return $contact_id;
564                 }
565         } elseif ($uid != 0) {
566                 // Non-existing user-specific contact, exiting
567                 return 0;
568         }
569
570         $data = Probe::uri($url);
571
572         // Last try in gcontact for unsupported networks
573         if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO))) {
574                 if ($uid != 0) {
575                         return 0;
576                 }
577
578                 // Get data from the gcontact table
579                 $gcontacts = q("SELECT `name`, `nick`, `url`, `photo`, `addr`, `alias`, `network` FROM `gcontact` WHERE `nurl` = '%s'",
580                          dbesc(normalise_link($url)));
581                 if (!$gcontacts) {
582                         return 0;
583                 }
584
585                 $data = $gcontacts[0];
586         }
587
588         $url = $data["url"];
589
590         if (!$contact_id) {
591                 q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,
592                                         `name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`,
593                                         `batch`, `request`, `confirm`, `poco`, `name-date`, `uri-date`,
594                                         `writable`, `blocked`, `readonly`, `pending`)
595                                         VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', 1, 0, 0, 0)",
596                         intval($uid),
597                         dbesc(datetime_convert()),
598                         dbesc($data["url"]),
599                         dbesc(normalise_link($data["url"])),
600                         dbesc($data["addr"]),
601                         dbesc($data["alias"]),
602                         dbesc($data["notify"]),
603                         dbesc($data["poll"]),
604                         dbesc($data["name"]),
605                         dbesc($data["nick"]),
606                         dbesc($data["photo"]),
607                         dbesc($data["network"]),
608                         dbesc($data["pubkey"]),
609                         intval(CONTACT_IS_SHARING),
610                         intval($data["priority"]),
611                         dbesc($data["batch"]),
612                         dbesc($data["request"]),
613                         dbesc($data["confirm"]),
614                         dbesc($data["poco"]),
615                         dbesc(datetime_convert()),
616                         dbesc(datetime_convert())
617                 );
618
619                 $contacts = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2",
620                                 dbesc(normalise_link($data["url"])),
621                                 intval($uid));
622                 if (!dbm::is_result($contacts)) {
623                         return 0;
624                 }
625
626                 $contact_id = $contacts[0]["id"];
627
628                 // Update the newly created contact from data in the gcontact table
629                 $gcontacts = q("SELECT `location`, `about`, `keywords`, `gender` FROM `gcontact` WHERE `nurl` = '%s'",
630                          dbesc(normalise_link($data["url"])));
631                 if (dbm::is_result($gcontacts)) {
632                         logger("Update contact " . $data["url"] . ' from gcontact');
633                         q("UPDATE `contact` SET `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `id` = %d",
634                                 dbesc($gcontacts[0]["location"]), dbesc($gcontacts[0]["about"]), dbesc($gcontacts[0]["keywords"]),
635                                 dbesc($gcontacts[0]["gender"]), intval($contact_id));
636                 }
637         }
638
639         if (count($contacts) > 1 && $uid == 0 && $contact_id != 0 && $url != "") {
640                 q("DELETE FROM `contact` WHERE `nurl` = '%s' AND `id` != %d AND NOT `self`",
641                         dbesc(normalise_link($url)),
642                         intval($contact_id));
643         }
644
645         require_once "Photo.php";
646
647         update_contact_avatar($data["photo"], $uid, $contact_id);
648
649         $contacts = q("SELECT `addr`, `alias`, `name`, `nick` FROM `contact` WHERE `id` = %d", intval($contact_id));
650
651         // This condition should always be true
652         if (!dbm::is_result($contacts)) {
653                 return $contact_id;
654         }
655
656         // Only update if there had something been changed
657         if ($data["addr"] != $contacts[0]["addr"] ||
658                 $data["alias"] != $contacts[0]["alias"] ||
659                 $data["name"] != $contacts[0]["name"] ||
660                 $data["nick"] != $contacts[0]["nick"]) {
661                 q("UPDATE `contact` SET `addr` = '%s', `alias` = '%s', `name` = '%s', `nick` = '%s',
662                         `name-date` = '%s', `uri-date` = '%s' WHERE `id` = %d",
663                         dbesc($data["addr"]),
664                         dbesc($data["alias"]),
665                         dbesc($data["name"]),
666                         dbesc($data["nick"]),
667                         dbesc(datetime_convert()),
668                         dbesc(datetime_convert()),
669                         intval($contact_id)
670                 );
671         }
672
673         return $contact_id;
674 }
675
676 /**
677  * @brief Returns posts from a given gcontact
678  *
679  * @param App $a argv application class
680  * @param int $gcontact_id Global contact
681  *
682  * @return string posts in HTML
683  */
684 function posts_from_gcontact(App $a, $gcontact_id) {
685
686         require_once 'include/conversation.php';
687
688         // There are no posts with "uid = 0" with connector networks
689         // This speeds up the query a lot
690         $r = q("SELECT `network` FROM `gcontact` WHERE `id` = %d", dbesc($gcontact_id));
691         if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
692                 $sql = "(`item`.`uid` = 0 OR  (`item`.`uid` = %d AND `item`.`private`))";
693         else
694                 $sql = "`item`.`uid` = %d";
695
696         $r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
697                         `author-name` AS `name`, `owner-avatar` AS `photo`,
698                         `owner-link` AS `url`, `owner-avatar` AS `thumb`
699                 FROM `item`
700                 WHERE `gcontact-id` = %d AND $sql AND
701                         NOT `deleted` AND NOT `moderated` AND `visible`
702                 ORDER BY `item`.`created` DESC LIMIT %d, %d",
703                 intval($gcontact_id),
704                 intval(local_user()),
705                 intval($a->pager['start']),
706                 intval($a->pager['itemspage'])
707         );
708
709         $o = conversation($a, $r, 'community', false);
710
711         $o .= alt_pager($a, count($r));
712
713         return $o;
714 }
715 /**
716  * @brief Returns posts from a given contact url
717  *
718  * @param App $a argv application class
719  * @param string $contact_url Contact URL
720  *
721  * @return string posts in HTML
722  */
723 function posts_from_contact_url(App $a, $contact_url) {
724
725         require_once 'include/conversation.php';
726
727         // There are no posts with "uid = 0" with connector networks
728         // This speeds up the query a lot
729         $r = q("SELECT `network`, `id` AS `author-id` FROM `contact`
730                 WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0",
731                 dbesc(normalise_link($contact_url)));
732         if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
733                 $sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND `item`.`private`))";
734         } else {
735                 $sql = "`item`.`uid` = %d";
736         }
737
738         if (!dbm::is_result($r)) {
739                 return '';
740         }
741
742         $author_id = intval($r[0]["author-id"]);
743
744         $r = q(item_query()." AND `item`.`author-id` = %d AND ".$sql.
745                 " ORDER BY `item`.`created` DESC LIMIT %d, %d",
746                 intval($author_id),
747                 intval(local_user()),
748                 intval($a->pager['start']),
749                 intval($a->pager['itemspage'])
750         );
751
752         $o = conversation($a, $r, 'community', false);
753
754         $o .= alt_pager($a, count($r));
755
756         return $o;
757 }
758
759 /**
760  * @brief Returns a formatted location string from the given profile array
761  *
762  * @param array $profile Profile array (Generated from the "profile" table)
763  *
764  * @return string Location string
765  */
766 function formatted_location($profile) {
767         $location = '';
768
769         if($profile['locality'])
770                 $location .= $profile['locality'];
771
772         if($profile['region'] && ($profile['locality'] != $profile['region'])) {
773                 if($location)
774                         $location .= ', ';
775
776                 $location .= $profile['region'];
777         }
778
779         if($profile['country-name']) {
780                 if($location)
781                         $location .= ', ';
782
783                 $location .= $profile['country-name'];
784         }
785
786         return $location;
787 }
788
789 /**
790  * @brief Returns the account type name
791  *
792  * The function can be called with either the user or the contact array
793  *
794  * @param array $contact contact or user array
795  */
796 function account_type($contact) {
797
798         // There are several fields that indicate that the contact or user is a forum
799         // "page-flags" is a field in the user table,
800         // "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
801         // "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
802         if((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
803                 || (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
804                 || (isset($contact['forum']) && intval($contact['forum']))
805                 || (isset($contact['prv']) && intval($contact['prv']))
806                 || (isset($contact['community']) && intval($contact['community'])))
807                 $type = ACCOUNT_TYPE_COMMUNITY;
808         else
809                 $type = ACCOUNT_TYPE_PERSON;
810
811         // The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
812         if (isset($contact["contact-type"]))
813                 $type = $contact["contact-type"];
814         if (isset($contact["account-type"]))
815                 $type = $contact["account-type"];
816
817         switch($type) {
818                 case ACCOUNT_TYPE_ORGANISATION:
819                         $account_type = t("Organisation");
820                         break;
821                 case ACCOUNT_TYPE_NEWS:
822                         $account_type = t('News');
823                         break;
824                 case ACCOUNT_TYPE_COMMUNITY:
825                         $account_type = t("Forum");
826                         break;
827                 default:
828                         $account_type = "";
829                         break;
830         }
831
832         return $account_type;
833 }