]> git.mxchange.org Git - friendica.git/blob - include/Contact.php
fea4a2aaf1537c35e2d3e3a4bd26225a415ee832
[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         $contact = dba::select('contact', array('id', 'avatar-date'), array('nurl' => normalise_link($url), 'uid' => $uid), array('limit' => 1));
531
532         // Then the addr (nick@server.tld)
533         if (!dbm::is_result($contact)) {
534                 $contact = dba::select('contact', array('id', 'avatar-date'), array('addr' => $url, 'uid' => $uid), array('limit' => 1));
535         }
536
537         // Then the alias (which could be anything)
538         if (!dbm::is_result($contact)) {
539                 $r = dba::p("SELECT `id`, `avatar-date` FROM `contact` WHERE `alias` IN (?, ?) AND `uid` = ? LIMIT 1",
540                                 $url, normalise_link($url), $uid);
541                 $contact = dba::fetch($r);
542                 dba::close($r);
543         }
544
545         if (dbm::is_result($contact)) {
546                 $contact_id = $contact["id"];
547
548                 // Update the contact every 7 days
549                 $update_contact = ($contact['avatar-date'] < datetime_convert('','','now -7 days'));
550
551                 if (!$update_contact || $no_update) {
552                         return $contact_id;
553                 }
554         } elseif ($uid != 0) {
555                 // Non-existing user-specific contact, exiting
556                 return 0;
557         }
558
559         $data = Probe::uri($url);
560
561         // Last try in gcontact for unsupported networks
562         if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO))) {
563                 if ($uid != 0) {
564                         return 0;
565                 }
566
567                 // Get data from the gcontact table
568                 $gcontacts = dba::select('gcontact', array('name', 'nick', 'url', 'photo', 'addr', 'alias', 'network'),
569                                                 array('nurl' => normalise_link($url)), array('limit' => 1));
570                 if (!$gcontacts) {
571                         return 0;
572                 }
573
574                 $data = $gcontacts;
575         }
576
577         $url = $data["url"];
578
579         if (!$contact_id) {
580                 if (!isset($data['priority'])) {
581                         $data['priority'] = 0;
582                 }
583                 if (!isset($data['batch'])) {
584                         $data['batch'] = '';
585                 }
586                 dba::insert('contact', array('uid' => $uid, 'created' => datetime_convert(), 'url' => $data["url"],
587                                         'nurl' => normalise_link($data["url"]), 'addr' => $data["addr"],
588                                         'alias' => $data["alias"], 'notify' => $data["notify"], 'poll' => $data["poll"],
589                                         'name' => $data["name"], 'nick' => $data["nick"], 'photo' => $data["photo"],
590                                         'network' => $data["network"], 'pubkey' => $data["pubkey"],
591                                         'rel' => CONTACT_IS_SHARING, 'priority' => $data["priority"],
592                                         'batch' => $data["batch"], 'request' => $data["request"],
593                                         'confirm' => $data["confirm"], 'poco' => $data["poco"],
594                                         'name-date' => datetime_convert(), 'uri-date' => datetime_convert(),
595                                         'avatar-date' => datetime_convert(), 'writable' => 1, 'blocked' => 0,
596                                         'readonly' => 0, 'pending' => 0));
597
598                 $contacts = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2",
599                                 dbesc(normalise_link($data["url"])),
600                                 intval($uid));
601                 if (!dbm::is_result($contacts)) {
602                         return 0;
603                 }
604
605                 $contact_id = $contacts[0]["id"];
606
607                 // Update the newly created contact from data in the gcontact table
608                 $gcontact = dba::select('gcontact', array('location', 'about', 'keywords', 'gender'),
609                                         array('nurl' => normalise_link($data["url"])), array('limit' => 1));
610                 if (dbm::is_result($gcontact)) {
611                         dba::update('contact', $gcontact, array('id' => $contact_id));
612                 }
613
614                 if (count($contacts) > 1 && $uid == 0 && $contact_id != 0 && $data["url"] != "") {
615                         dba::e("DELETE FROM `contact` WHERE `nurl` = ? AND `uid` = 0 AND `id` != ? AND NOT `self`",
616                                 normalise_link($data["url"]), $contact_id);
617                 }
618         }
619
620         require_once "Photo.php";
621
622         update_contact_avatar($data["photo"], $uid, $contact_id);
623
624         $contact = dba::select('contact', array('addr', 'alias', 'name', 'nick', 'avatar-date'),
625                                 array('id' => $contact_id), array('limit' => 1));
626
627         // This condition should always be true
628         if (!dbm::is_result($contact)) {
629                 return $contact_id;
630         }
631
632         $updated = array('addr' => $data['addr'],
633                         'alias' => $data['alias'],
634                         'name' => $data['name'],
635                         'nick' => $data['nick']);
636
637         if (($data["addr"] != $contact["addr"]) || ($data["alias"] != $contact["alias"])) {
638                 $updated['uri-date'] = datetime_convert();
639         }
640         if (($data["name"] != $contact["name"]) || ($data["nick"] != $contact["nick"])) {
641                 $updated['name-date'] = datetime_convert();
642         }
643
644         $updated['avatar-date'] = datetime_convert();
645
646         dba::update('contact', $updated, array('id' => $contact_id), $contact);
647
648         return $contact_id;
649 }
650
651 /**
652  * @brief Returns posts from a given gcontact
653  *
654  * @param App $a argv application class
655  * @param int $gcontact_id Global contact
656  *
657  * @return string posts in HTML
658  */
659 function posts_from_gcontact(App $a, $gcontact_id) {
660
661         require_once 'include/conversation.php';
662
663         // There are no posts with "uid = 0" with connector networks
664         // This speeds up the query a lot
665         $r = q("SELECT `network` FROM `gcontact` WHERE `id` = %d", dbesc($gcontact_id));
666         if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
667                 $sql = "(`item`.`uid` = 0 OR  (`item`.`uid` = %d AND `item`.`private`))";
668         else
669                 $sql = "`item`.`uid` = %d";
670
671         $r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
672                         `author-name` AS `name`, `owner-avatar` AS `photo`,
673                         `owner-link` AS `url`, `owner-avatar` AS `thumb`
674                 FROM `item`
675                 WHERE `gcontact-id` = %d AND $sql AND
676                         NOT `deleted` AND NOT `moderated` AND `visible`
677                 ORDER BY `item`.`created` DESC LIMIT %d, %d",
678                 intval($gcontact_id),
679                 intval(local_user()),
680                 intval($a->pager['start']),
681                 intval($a->pager['itemspage'])
682         );
683
684         $o = conversation($a, $r, 'community', false);
685
686         $o .= alt_pager($a, count($r));
687
688         return $o;
689 }
690 /**
691  * @brief Returns posts from a given contact url
692  *
693  * @param App $a argv application class
694  * @param string $contact_url Contact URL
695  *
696  * @return string posts in HTML
697  */
698 function posts_from_contact_url(App $a, $contact_url) {
699
700         require_once 'include/conversation.php';
701
702         // There are no posts with "uid = 0" with connector networks
703         // This speeds up the query a lot
704         $r = q("SELECT `network`, `id` AS `author-id` FROM `contact`
705                 WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0",
706                 dbesc(normalise_link($contact_url)));
707         if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
708                 $sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND `item`.`private`))";
709         } else {
710                 $sql = "`item`.`uid` = %d";
711         }
712
713         if (!dbm::is_result($r)) {
714                 return '';
715         }
716
717         $author_id = intval($r[0]["author-id"]);
718
719         $r = q(item_query()." AND `item`.`author-id` = %d AND ".$sql.
720                 " ORDER BY `item`.`created` DESC LIMIT %d, %d",
721                 intval($author_id),
722                 intval(local_user()),
723                 intval($a->pager['start']),
724                 intval($a->pager['itemspage'])
725         );
726
727         $o = conversation($a, $r, 'community', false);
728
729         $o .= alt_pager($a, count($r));
730
731         return $o;
732 }
733
734 /**
735  * @brief Returns a formatted location string from the given profile array
736  *
737  * @param array $profile Profile array (Generated from the "profile" table)
738  *
739  * @return string Location string
740  */
741 function formatted_location($profile) {
742         $location = '';
743
744         if($profile['locality'])
745                 $location .= $profile['locality'];
746
747         if($profile['region'] && ($profile['locality'] != $profile['region'])) {
748                 if($location)
749                         $location .= ', ';
750
751                 $location .= $profile['region'];
752         }
753
754         if($profile['country-name']) {
755                 if($location)
756                         $location .= ', ';
757
758                 $location .= $profile['country-name'];
759         }
760
761         return $location;
762 }
763
764 /**
765  * @brief Returns the account type name
766  *
767  * The function can be called with either the user or the contact array
768  *
769  * @param array $contact contact or user array
770  */
771 function account_type($contact) {
772
773         // There are several fields that indicate that the contact or user is a forum
774         // "page-flags" is a field in the user table,
775         // "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
776         // "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
777         if((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
778                 || (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
779                 || (isset($contact['forum']) && intval($contact['forum']))
780                 || (isset($contact['prv']) && intval($contact['prv']))
781                 || (isset($contact['community']) && intval($contact['community'])))
782                 $type = ACCOUNT_TYPE_COMMUNITY;
783         else
784                 $type = ACCOUNT_TYPE_PERSON;
785
786         // The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
787         if (isset($contact["contact-type"]))
788                 $type = $contact["contact-type"];
789         if (isset($contact["account-type"]))
790                 $type = $contact["account-type"];
791
792         switch($type) {
793                 case ACCOUNT_TYPE_ORGANISATION:
794                         $account_type = t("Organisation");
795                         break;
796                 case ACCOUNT_TYPE_NEWS:
797                         $account_type = t('News');
798                         break;
799                 case ACCOUNT_TYPE_COMMUNITY:
800                         $account_type = t("Forum");
801                         break;
802                 default:
803                         $account_type = "";
804                         break;
805         }
806
807         return $account_type;
808 }