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