]> git.mxchange.org Git - friendica.git/blob - mod/contacts.php
Remove include/oembed and mod/oembed
[friendica.git] / mod / contacts.php
1 <?php
2 /**
3  * @file mod/contacts.php
4  */
5 use Friendica\App;
6 use Friendica\Core\System;
7 use Friendica\Core\Worker;
8 use Friendica\Database\DBM;
9 use Friendica\Model\Contact;
10 use Friendica\Model\GContact;
11 use Friendica\Model\Group;
12 use Friendica\Network\Probe;
13
14 require_once 'include/contact_selectors.php';
15 require_once 'mod/proxy.php';
16 require_once 'include/follow.php';
17
18 function contacts_init(App $a) {
19         if (! local_user()) {
20                 return;
21         }
22
23         $contact_id = 0;
24
25         if((($a->argc == 2) && intval($a->argv[1])) || (($a->argc == 3) && intval($a->argv[1]) && ($a->argv[2] == "posts"))) {
26                 $contact_id = intval($a->argv[1]);
27                 $r = q("SELECT * FROM `contact` WHERE `uid` = %d and `id` = %d LIMIT 1",
28                         intval(local_user()),
29                         intval($contact_id)
30                 );
31                 if (! DBM::is_result($r)) {
32                         $contact_id = 0;
33                 }
34         }
35
36         require_once 'include/contact_widgets.php';
37
38         if ($_GET['nets'] == "all") {
39                 $_GET['nets'] = "";
40         }
41
42         if (! x($a->page,'aside')) {
43                 $a->page['aside'] = '';
44         }
45
46         if ($contact_id) {
47                 $a->data['contact'] = $r[0];
48
49                 if (($a->data['contact']['network'] != "") && ($a->data['contact']['network'] != NETWORK_DFRN)) {
50                         $networkname = format_network_name($a->data['contact']['network'],$a->data['contact']['url']);
51                 } else {
52                         $networkname = '';
53                 }
54
55                 /// @TODO Add nice spaces
56                 $vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"),array(
57                         '$name' => htmlentities($a->data['contact']['name']),
58                         '$photo' => $a->data['contact']['photo'],
59                         '$url' => ($a->data['contact']['network'] == NETWORK_DFRN) ? "redir/".$a->data['contact']['id'] : $a->data['contact']['url'],
60                         '$addr' => (($a->data['contact']['addr'] != "") ? ($a->data['contact']['addr']) : ""),
61                         '$network_name' => $networkname,
62                         '$network' => t('Network:'),
63                         '$account_type' => Contact::getAccountType($a->data['contact'])
64                 ));
65
66                 $finpeople_widget = '';
67                 $follow_widget = '';
68                 $networks_widget = '';
69         } else {
70                 $vcard_widget = '';
71                 $networks_widget .= networks_widget('contacts',$_GET['nets']);
72                 if (isset($_GET['add'])) {
73                         $follow_widget = follow_widget($_GET['add']);
74                 } else {
75                         $follow_widget = follow_widget();
76                 }
77
78                 $findpeople_widget .= findpeople_widget();
79         }
80
81         $groups_widget .= Group::sidebarWidget('contacts','group','full',0,$contact_id);
82
83         $a->page['aside'] .= replace_macros(get_markup_template("contacts-widget-sidebar.tpl"),array(
84                 '$vcard_widget' => $vcard_widget,
85                 '$findpeople_widget' => $findpeople_widget,
86                 '$follow_widget' => $follow_widget,
87                 '$groups_widget' => $groups_widget,
88                 '$networks_widget' => $networks_widget
89         ));
90
91         $base = System::baseUrl();
92         $tpl = get_markup_template("contacts-head.tpl");
93         $a->page['htmlhead'] .= replace_macros($tpl,array(
94                 '$baseurl' => System::baseUrl(true),
95                 '$base' => $base
96         ));
97
98         $tpl = get_markup_template("contacts-end.tpl");
99         $a->page['end'] .= replace_macros($tpl,array(
100                 '$baseurl' => System::baseUrl(true),
101                 '$base' => $base
102         ));
103
104
105 }
106
107 function contacts_batch_actions(App $a) {
108         $contacts_id = $_POST['contact_batch'];
109         if (!is_array($contacts_id)) return;
110
111         $orig_records = q("SELECT * FROM `contact` WHERE `id` IN (%s) AND `uid` = %d AND `self` = 0",
112                 implode(",", $contacts_id),
113                 intval(local_user())
114         );
115
116         $count_actions=0;
117         foreach($orig_records as $orig_record) {
118                 $contact_id = $orig_record['id'];
119                 if (x($_POST, 'contacts_batch_update')) {
120                         _contact_update($contact_id);
121                         $count_actions++;
122                 }
123                 if (x($_POST, 'contacts_batch_block')) {
124                         $r  = _contact_block($contact_id, $orig_record);
125                         if ($r) $count_actions++;
126                 }
127                 if (x($_POST, 'contacts_batch_ignore')) {
128                         $r = _contact_ignore($contact_id, $orig_record);
129                         if ($r) $count_actions++;
130                 }
131                 if (x($_POST, 'contacts_batch_archive')) {
132                         $r = _contact_archive($contact_id, $orig_record);
133                         if ($r) $count_actions++;
134                 }
135                 if (x($_POST, 'contacts_batch_drop')) {
136                         _contact_drop($orig_record);
137                         $count_actions++;
138                 }
139         }
140         if ($count_actions>0) {
141                 info ( sprintf( tt("%d contact edited.", "%d contacts edited.", $count_actions), $count_actions) );
142         }
143
144         if (x($_SESSION,'return_url')) {
145                 goaway('' . $_SESSION['return_url']);
146         }
147         else {
148                 goaway('contacts');
149         }
150
151 }
152
153
154 function contacts_post(App $a) {
155
156         if (! local_user()) {
157                 return;
158         }
159
160         if ($a->argv[1]==="batch") {
161                 contacts_batch_actions($a);
162                 return;
163         }
164
165         $contact_id = intval($a->argv[1]);
166         if (! $contact_id) {
167                 return;
168         }
169
170         $orig_record = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
171                 intval($contact_id),
172                 intval(local_user())
173         );
174
175         if (! count($orig_record)) {
176                 notice( t('Could not access contact record.') . EOL);
177                 goaway('contacts');
178                 return; // NOTREACHED
179         }
180
181         call_hooks('contact_edit_post', $_POST);
182
183         $profile_id = intval($_POST['profile-assign']);
184         if ($profile_id) {
185                 $r = q("SELECT `id` FROM `profile` WHERE `id` = %d AND `uid` = %d LIMIT 1",
186                         intval($profile_id),
187                         intval(local_user())
188                 );
189                 if (! DBM::is_result($r)) {
190                         notice( t('Could not locate selected profile.') . EOL);
191                         return;
192                 }
193         }
194
195         $hidden = intval($_POST['hidden']);
196
197         $notify = intval($_POST['notify']);
198
199         $fetch_further_information = intval($_POST['fetch_further_information']);
200
201         $ffi_keyword_blacklist = escape_tags(trim($_POST['ffi_keyword_blacklist']));
202
203         $priority = intval($_POST['poll']);
204         if($priority > 5 || $priority < 0)
205                 $priority = 0;
206
207         $info = escape_tags(trim($_POST['info']));
208
209         $r = q("UPDATE `contact` SET `profile-id` = %d, `priority` = %d , `info` = '%s',
210                 `hidden` = %d, `notify_new_posts` = %d, `fetch_further_information` = %d,
211                 `ffi_keyword_blacklist` = '%s' WHERE `id` = %d AND `uid` = %d",
212                 intval($profile_id),
213                 intval($priority),
214                 dbesc($info),
215                 intval($hidden),
216                 intval($notify),
217                 intval($fetch_further_information),
218                 dbesc($ffi_keyword_blacklist),
219                 intval($contact_id),
220                 intval(local_user())
221         );
222         if($r)
223                 info( t('Contact updated.') . EOL);
224         else
225                 notice( t('Failed to update contact record.') . EOL);
226
227         $r = q("select * from contact where id = %d and uid = %d limit 1",
228                 intval($contact_id),
229                 intval(local_user())
230         );
231         if($r && DBM::is_result($r))
232                 $a->data['contact'] = $r[0];
233
234         return;
235
236 }
237
238 /*contact actions*/
239 function _contact_update($contact_id) {
240         $r = q("SELECT `uid`, `url`, `network` FROM `contact` WHERE `id` = %d", intval($contact_id));
241         if (!$r)
242                 return;
243
244         $uid = $r[0]["uid"];
245
246         if ($uid != local_user())
247                 return;
248
249         if ($r[0]["network"] == NETWORK_OSTATUS) {
250                 $result = new_contact($uid, $r[0]["url"], false, $r[0]["network"]);
251
252                 if ($result['success'])
253                         $r = q("UPDATE `contact` SET `subhub` = 1 WHERE `id` = %d",
254                                 intval($contact_id));
255         } else
256                 // pull feed and consume it, which should subscribe to the hub.
257                 Worker::add(PRIORITY_HIGH, "OnePoll", $contact_id, "force");
258 }
259
260 function _contact_update_profile($contact_id) {
261         $r = q("SELECT `uid`, `url`, `network` FROM `contact` WHERE `id` = %d", intval($contact_id));
262         if (!$r)
263                 return;
264
265         $uid = $r[0]["uid"];
266
267         if ($uid != local_user())
268                 return;
269
270         $data = Probe::uri($r[0]["url"], "", 0, false);
271
272         // "Feed" or "Unknown" is mostly a sign of communication problems
273         if ((in_array($data["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) && ($data["network"] != $r[0]["network"]))
274                 return;
275
276         $updatefields = array("name", "nick", "url", "addr", "batch", "notify", "poll", "request", "confirm",
277                                 "poco", "network", "alias");
278         $update = array();
279
280         if ($data["network"] == NETWORK_OSTATUS) {
281                 $result = new_contact($uid, $data["url"], false);
282
283                 if ($result['success'])
284                         $update["subhub"] = true;
285         }
286
287         foreach($updatefields AS $field)
288                 if (isset($data[$field]) && ($data[$field] != ""))
289                         $update[$field] = $data[$field];
290
291         $update["nurl"] = normalise_link($data["url"]);
292
293         $query = "";
294
295         if (isset($data["priority"]) && ($data["priority"] != 0))
296                 $query = "`priority` = ".intval($data["priority"]);
297
298         foreach($update AS $key => $value) {
299                 if ($query != "")
300                         $query .= ", ";
301
302                 $query .= "`".$key."` = '".dbesc($value)."'";
303         }
304
305         if ($query == "")
306                 return;
307
308         $r = q("UPDATE `contact` SET $query WHERE `id` = %d AND `uid` = %d",
309                 intval($contact_id),
310                 intval(local_user())
311         );
312
313         // Update the entry in the contact table
314         Contact::updateAvatar($data['photo'], local_user(), $contact_id, true);
315
316         // Update the entry in the gcontact table
317         GContact::updateFromProbe($data["url"]);
318 }
319
320 function _contact_block($contact_id, $orig_record) {
321         $blocked = (($orig_record['blocked']) ? 0 : 1);
322         $r = q("UPDATE `contact` SET `blocked` = %d WHERE `id` = %d AND `uid` = %d",
323                 intval($blocked),
324                 intval($contact_id),
325                 intval(local_user())
326         );
327         return $r;
328
329 }
330 function _contact_ignore($contact_id, $orig_record) {
331         $readonly = (($orig_record['readonly']) ? 0 : 1);
332         $r = q("UPDATE `contact` SET `readonly` = %d WHERE `id` = %d AND `uid` = %d",
333                 intval($readonly),
334                 intval($contact_id),
335                 intval(local_user())
336         );
337         return $r;
338 }
339 function _contact_archive($contact_id, $orig_record) {
340         $archived = (($orig_record['archive']) ? 0 : 1);
341         $r = q("UPDATE `contact` SET `archive` = %d WHERE `id` = %d AND `uid` = %d",
342                 intval($archived),
343                 intval($contact_id),
344                 intval(local_user())
345         );
346         if ($archived) {
347                 q("UPDATE `item` SET `private` = 2 WHERE `contact-id` = %d AND `uid` = %d", intval($contact_id), intval(local_user()));
348         }
349         return $r;
350 }
351
352 function _contact_drop($orig_record)
353 {
354         $a = get_app();
355
356         $r = q("SELECT `contact`.*, `user`.* FROM `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid`
357                 WHERE `user`.`uid` = %d AND `contact`.`self` LIMIT 1",
358                 intval($a->user['uid'])
359         );
360         if (!DBM::is_result($r)) {
361                 return;
362         }
363
364         Contact::terminateFriendship($r[0], $orig_record);
365         Contact::remove($orig_record['id']);
366 }
367
368
369 function contacts_content(App $a) {
370
371         $sort_type = 0;
372         $o = '';
373         nav_set_selected('contacts');
374
375
376         if (! local_user()) {
377                 notice( t('Permission denied.') . EOL);
378                 return;
379         }
380
381         if($a->argc == 3) {
382
383                 $contact_id = intval($a->argv[1]);
384                 if(! $contact_id)
385                         return;
386
387                 $cmd = $a->argv[2];
388
389                 $orig_record = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d AND `self` = 0 LIMIT 1",
390                         intval($contact_id),
391                         intval(local_user())
392                 );
393
394                 if(! count($orig_record)) {
395                         notice( t('Could not access contact record.') . EOL);
396                         goaway('contacts');
397                         return; // NOTREACHED
398                 }
399
400                 if($cmd === 'update') {
401                         _contact_update($contact_id);
402                         goaway('contacts/' . $contact_id);
403                         // NOTREACHED
404                 }
405
406                 if($cmd === 'updateprofile') {
407                         _contact_update_profile($contact_id);
408                         goaway('crepair/' . $contact_id);
409                         // NOTREACHED
410                 }
411
412                 if($cmd === 'block') {
413                         $r = _contact_block($contact_id, $orig_record[0]);
414                         if ($r) {
415                                 $blocked = (($orig_record[0]['blocked']) ? 0 : 1);
416                                 info((($blocked) ? t('Contact has been blocked') : t('Contact has been unblocked')).EOL);
417                         }
418
419                         goaway('contacts/' . $contact_id);
420                         return; // NOTREACHED
421                 }
422
423                 if($cmd === 'ignore') {
424                         $r = _contact_ignore($contact_id, $orig_record[0]);
425                         if ($r) {
426                                 $readonly = (($orig_record[0]['readonly']) ? 0 : 1);
427                                 info((($readonly) ? t('Contact has been ignored') : t('Contact has been unignored')).EOL);
428                         }
429
430                         goaway('contacts/' . $contact_id);
431                         return; // NOTREACHED
432                 }
433
434
435                 if($cmd === 'archive') {
436                         $r = _contact_archive($contact_id, $orig_record[0]);
437                         if ($r) {
438                                 $archived = (($orig_record[0]['archive']) ? 0 : 1);
439                                 info((($archived) ? t('Contact has been archived') : t('Contact has been unarchived')).EOL);
440                         }
441
442                         goaway('contacts/' . $contact_id);
443                         return; // NOTREACHED
444                 }
445
446                 if($cmd === 'drop') {
447
448                         // Check if we should do HTML-based delete confirmation
449                         if($_REQUEST['confirm']) {
450                                 // <form> can't take arguments in its "action" parameter
451                                 // so add any arguments as hidden inputs
452                                 $query = explode_querystring($a->query_string);
453                                 $inputs = array();
454                                 foreach($query['args'] as $arg) {
455                                         if(strpos($arg, 'confirm=') === false) {
456                                                 $arg_parts = explode('=', $arg);
457                                                 $inputs[] = array('name' => $arg_parts[0], 'value' => $arg_parts[1]);
458                                         }
459                                 }
460
461                                 $a->page['aside'] = '';
462
463                                 return replace_macros(get_markup_template('contact_drop_confirm.tpl'), array(
464                                         '$header' => t('Drop contact'),
465                                         '$contact' => _contact_detail_for_template($orig_record[0]),
466                                         '$method' => 'get',
467                                         '$message' => t('Do you really want to delete this contact?'),
468                                         '$extra_inputs' => $inputs,
469                                         '$confirm' => t('Yes'),
470                                         '$confirm_url' => $query['base'],
471                                         '$confirm_name' => 'confirmed',
472                                         '$cancel' => t('Cancel'),
473                                 ));
474                         }
475                         // Now check how the user responded to the confirmation query
476                         if ($_REQUEST['canceled']) {
477                                 if (x($_SESSION,'return_url')) {
478                                         goaway('' . $_SESSION['return_url']);
479                                 }
480                                 else {
481                                         goaway('contacts');
482                                 }
483                         }
484
485                         _contact_drop($orig_record[0]);
486                         info( t('Contact has been removed.') . EOL );
487                         if (x($_SESSION,'return_url')) {
488                                 goaway('' . $_SESSION['return_url']);
489                         }
490                         else {
491                                 goaway('contacts');
492                         }
493                         return; // NOTREACHED
494                 }
495                 if ($cmd === 'posts') {
496                         return contact_posts($a, $contact_id);
497                 }
498         }
499
500
501
502         $_SESSION['return_url'] = $a->query_string;
503
504         if((x($a->data,'contact')) && (is_array($a->data['contact']))) {
505
506                 $contact_id = $a->data['contact']['id'];
507                 $contact = $a->data['contact'];
508
509                 $a->page['htmlhead'] .= replace_macros(get_markup_template('contact_head.tpl'), array(
510                         '$baseurl' => System::baseUrl(true),
511                 ));
512                 $a->page['end'] .= replace_macros(get_markup_template('contact_end.tpl'), array(
513                         '$baseurl' => System::baseUrl(true),
514                 ));
515
516                 require_once 'include/contact_selectors.php';
517
518                 $tpl = get_markup_template("contact_edit.tpl");
519
520                 switch($contact['rel']) {
521                         case CONTACT_IS_FRIEND:
522                                 $dir_icon = 'images/lrarrow.gif';
523                                 $relation_text = t('You are mutual friends with %s');
524                                 break;
525                         case CONTACT_IS_FOLLOWER;
526                                 $dir_icon = 'images/larrow.gif';
527                                 $relation_text = t('You are sharing with %s');
528                                 break;
529
530                         case CONTACT_IS_SHARING;
531                                 $dir_icon = 'images/rarrow.gif';
532                                 $relation_text = t('%s is sharing with you');
533                                 break;
534                         default:
535                                 break;
536                 }
537
538                 if(!in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
539                                 $relation_text = "";
540
541                 $relation_text = sprintf($relation_text,htmlentities($contact['name']));
542
543                 if(($contact['network'] === NETWORK_DFRN) && ($contact['rel'])) {
544                         $url = "redir/{$contact['id']}";
545                         $sparkle = ' class="sparkle" ';
546                 }
547                 else {
548                         $url = $contact['url'];
549                         $sparkle = '';
550                 }
551
552                 $insecure = t('Private communications are not available for this contact.');
553
554                 $last_update = (($contact['last-update'] <= NULL_DATE)
555                                 ? t('Never')
556                                 : datetime_convert('UTC',date_default_timezone_get(),$contact['last-update'],'D, j M Y, g:i A'));
557
558                 if ($contact['last-update'] > NULL_DATE) {
559                         $last_update .= ' ' . (($contact['last-update'] <= $contact['success_update']) ? t("\x28Update was successful\x29") : t("\x28Update was not successful\x29"));
560                 }
561                 $lblsuggest = (($contact['network'] === NETWORK_DFRN) ? t('Suggest friends') : '');
562
563                 $poll_enabled = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_FEED, NETWORK_MAIL));
564
565                 $nettype = sprintf( t('Network type: %s'),network_to_name($contact['network'], $contact["url"]));
566
567                 //$common = GlobalContact::countCommonFriends(local_user(),$contact['id']);
568                 //$common_text = (($common) ? sprintf( tt('%d contact in common','%d contacts in common', $common),$common) : '');
569
570                 $polling = (($contact['network'] === NETWORK_MAIL | $contact['network'] === NETWORK_FEED) ? 'polling' : '');
571
572                 //$x = GlobalContact::countAllFriends(local_user(), $contact['id']);
573                 //$all_friends = (($x) ? t('View all contacts') : '');
574
575                 // tabs
576                 $tab_str = contacts_tab($a, $contact_id, 2);
577
578                 $lost_contact = (($contact['archive'] && $contact['term-date'] > NULL_DATE && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : '');
579
580                 if ($contact['network'] == NETWORK_FEED) {
581                         $fetch_further_information = array('fetch_further_information',
582                                                         t('Fetch further information for feeds'),
583                                                         $contact['fetch_further_information'],
584                                                         t("Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn't contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags."),
585                                                                 array('0' => t('Disabled'),
586                                                                         '1' => t('Fetch information'),
587                                                                         '3' => t('Fetch keywords'),
588                                                                         '2' => t('Fetch information and keywords')));
589                 }
590                 if (in_array($contact['network'], array(NETWORK_FEED, NETWORK_MAIL)))
591                         $poll_interval = contact_poll_interval($contact['priority'],(! $poll_enabled));
592
593                 if ($contact['network'] == NETWORK_DFRN)
594                         $profile_select = contact_profile_assign($contact['profile-id'],(($contact['network'] !== NETWORK_DFRN) ? true : false));
595
596                 if (in_array($contact['network'], array(NETWORK_DIASPORA, NETWORK_OSTATUS))) {
597                         if ($contact['rel'] == CONTACT_IS_FOLLOWER) {
598                                 $follow = System::baseUrl(true)."/follow?url=".urlencode($contact["url"]);
599                                 $follow_text = t("Connect/Follow");
600                         } elseif ($contact['rel'] == CONTACT_IS_FRIEND) {
601                                 $follow = System::baseUrl(true)."/unfollow?url=".urlencode($contact["url"]);
602                                 $follow_text = t("Disconnect/Unfollow");
603                         }
604                 }
605
606                 // Load contactact related actions like hide, suggest, delete and others
607                 $contact_actions = contact_actions($contact);
608
609
610                 $o .= replace_macros($tpl, array(
611                         //'$header' => t('Contact Editor'),
612                         '$header' => t("Contact"),
613                         '$tab_str' => $tab_str,
614                         '$submit' => t('Submit'),
615                         '$lbl_vis1' => t('Profile Visibility'),
616                         '$lbl_vis2' => sprintf( t('Please choose the profile you would like to display to %s when viewing your profile securely.'), $contact['name']),
617                         '$lbl_info1' => t('Contact Information / Notes'),
618                         '$lbl_info2' => t('Their personal note'),
619                         '$reason' => trim(notags($contact['reason'])),
620                         '$infedit' => t('Edit contact notes'),
621                         '$common_text' => $common_text,
622                         '$common_link' => 'common/loc/' . local_user() . '/' . $contact['id'],
623                         '$all_friends' => $all_friends,
624                         '$relation_text' => $relation_text,
625                         '$visit' => sprintf( t('Visit %s\'s profile [%s]'),$contact['name'],$contact['url']),
626                         '$blockunblock' => t('Block/Unblock contact'),
627                         '$ignorecont' => t('Ignore contact'),
628                         '$lblcrepair' => t("Repair URL settings"),
629                         '$lblrecent' => t('View conversations'),
630                         '$lblsuggest' => $lblsuggest,
631                         //'$delete' => t('Delete contact'),
632                         '$nettype' => $nettype,
633                         '$poll_interval' => $poll_interval,
634                         '$poll_enabled' => $poll_enabled,
635                         '$lastupdtext' => t('Last update:'),
636                         '$lost_contact' => $lost_contact,
637                         '$updpub' => t('Update public posts'),
638                         '$last_update' => $last_update,
639                         '$udnow' => t('Update now'),
640                         '$follow' => $follow,
641                         '$follow_text' => $follow_text,
642                         '$profile_select' => $profile_select,
643                         '$contact_id' => $contact['id'],
644                         '$block_text' => (($contact['blocked']) ? t('Unblock') : t('Block') ),
645                         '$ignore_text' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ),
646                         '$insecure' => (($contact['network'] !== NETWORK_DFRN && $contact['network'] !== NETWORK_MAIL && $contact['network'] !== NETWORK_FACEBOOK && $contact['network'] !== NETWORK_DIASPORA) ? $insecure : ''),
647                         '$info' => $contact['info'],
648                         '$cinfo' => array('info', '', $contact['info'], ''),
649                         '$blocked' => (($contact['blocked']) ? t('Currently blocked') : ''),
650                         '$ignored' => (($contact['readonly']) ? t('Currently ignored') : ''),
651                         '$archived' => (($contact['archive']) ? t('Currently archived') : ''),
652                         '$pending' => (($contact['pending']) ? t('Awaiting connection acknowledge') : ''),
653                         '$hidden' => array('hidden', t('Hide this contact from others'), ($contact['hidden'] == 1), t('Replies/likes to your public posts <strong>may</strong> still be visible')),
654                         '$notify' => array('notify', t('Notification for new posts'), ($contact['notify_new_posts'] == 1), t('Send a notification of every new post of this contact')),
655                         '$fetch_further_information' => $fetch_further_information,
656                         '$ffi_keyword_blacklist' => $contact['ffi_keyword_blacklist'],
657                         '$ffi_keyword_blacklist' => array('ffi_keyword_blacklist', t('Blacklisted keywords'), $contact['ffi_keyword_blacklist'], t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')),
658                         '$photo' => $contact['photo'],
659                         '$name' => htmlentities($contact['name']),
660                         '$dir_icon' => $dir_icon,
661                         '$alt_text' => $alt_text,
662                         '$sparkle' => $sparkle,
663                         '$url' => $url,
664                         '$profileurllabel' => t('Profile URL'),
665                         '$profileurl' => $contact['url'],
666                         '$account_type' => Contact::getAccountType($contact),
667                         '$location' => bbcode($contact["location"]),
668                         '$location_label' => t("Location:"),
669                         '$xmpp' => bbcode($contact["xmpp"]),
670                         '$xmpp_label' => t("XMPP:"),
671                         '$about' => bbcode($contact["about"], false, false),
672                         '$about_label' => t("About:"),
673                         '$keywords' => $contact["keywords"],
674                         '$keywords_label' => t("Tags:"),
675                         '$contact_action_button' => t("Actions"),
676                         '$contact_actions' => $contact_actions,
677                         '$contact_status' => t("Status"),
678                         '$contact_settings_label' => t('Contact Settings'),
679                         '$contact_profile_label' => t("Profile"),
680
681                 ));
682
683                 $arr = array('contact' => $contact,'output' => $o);
684
685                 call_hooks('contact_edit', $arr);
686
687                 return $arr['output'];
688
689         }
690
691         $blocked = false;
692         $hidden = false;
693         $ignored = false;
694         $all = false;
695
696         if(($a->argc == 2) && ($a->argv[1] === 'all')) {
697                 $sql_extra = '';
698                 $all = true;
699         }
700         elseif(($a->argc == 2) && ($a->argv[1] === 'blocked')) {
701                 $sql_extra = " AND `blocked` = 1 ";
702                 $blocked = true;
703         }
704         elseif(($a->argc == 2) && ($a->argv[1] === 'hidden')) {
705                 $sql_extra = " AND `hidden` = 1 ";
706                 $hidden = true;
707         }
708         elseif(($a->argc == 2) && ($a->argv[1] === 'ignored')) {
709                 $sql_extra = " AND `readonly` = 1 ";
710                 $ignored = true;
711         }
712         elseif(($a->argc == 2) && ($a->argv[1] === 'archived')) {
713                 $sql_extra = " AND `archive` = 1 ";
714                 $archived = true;
715         }
716         else
717                 $sql_extra = " AND `blocked` = 0 ";
718
719         $search = ((x($_GET,'search')) ? notags(trim($_GET['search'])) : '');
720         $nets = ((x($_GET,'nets')) ? notags(trim($_GET['nets'])) : '');
721
722         $tabs = array(
723                 array(
724                         'label' => t('Suggestions'),
725                         'url'   => 'suggest',
726                         'sel'   => '',
727                         'title' => t('Suggest potential friends'),
728                         'id'    => 'suggestions-tab',
729                         'accesskey' => 'g',
730                 ),
731                 array(
732                         'label' => t('All Contacts'),
733                         'url'   => 'contacts/all',
734                         'sel'   => ($all) ? 'active' : '',
735                         'title' => t('Show all contacts'),
736                         'id'    => 'showall-tab',
737                         'accesskey' => 'l',
738                 ),
739                 array(
740                         'label' => t('Unblocked'),
741                         'url'   => 'contacts',
742                         'sel'   => ((! $all) && (! $blocked) && (! $hidden) && (! $search) && (! $nets) && (! $ignored) && (! $archived)) ? 'active' : '',
743                         'title' => t('Only show unblocked contacts'),
744                         'id'    => 'showunblocked-tab',
745                         'accesskey' => 'o',
746                 ),
747
748                 array(
749                         'label' => t('Blocked'),
750                         'url'   => 'contacts/blocked',
751                         'sel'   => ($blocked) ? 'active' : '',
752                         'title' => t('Only show blocked contacts'),
753                         'id'    => 'showblocked-tab',
754                         'accesskey' => 'b',
755                 ),
756
757                 array(
758                         'label' => t('Ignored'),
759                         'url'   => 'contacts/ignored',
760                         'sel'   => ($ignored) ? 'active' : '',
761                         'title' => t('Only show ignored contacts'),
762                         'id'    => 'showignored-tab',
763                         'accesskey' => 'i',
764                 ),
765
766                 array(
767                         'label' => t('Archived'),
768                         'url'   => 'contacts/archived',
769                         'sel'   => ($archived) ? 'active' : '',
770                         'title' => t('Only show archived contacts'),
771                         'id'    => 'showarchived-tab',
772                         'accesskey' => 'y',
773                 ),
774
775                 array(
776                         'label' => t('Hidden'),
777                         'url'   => 'contacts/hidden',
778                         'sel'   => ($hidden) ? 'active' : '',
779                         'title' => t('Only show hidden contacts'),
780                         'id'    => 'showhidden-tab',
781                         'accesskey' => 'h',
782                 ),
783
784         );
785
786         $tab_tpl = get_markup_template('common_tabs.tpl');
787         $t = replace_macros($tab_tpl, array('$tabs'=>$tabs));
788
789
790
791         $searching = false;
792         if($search) {
793                 $search_hdr = $search;
794                 $search_txt = dbesc(protect_sprintf(preg_quote($search)));
795                 $searching = true;
796         }
797         $sql_extra .= (($searching) ? " AND (name REGEXP '$search_txt' OR url REGEXP '$search_txt'  OR nick REGEXP '$search_txt') " : "");
798
799         if($nets)
800                 $sql_extra .= sprintf(" AND network = '%s' ", dbesc($nets));
801
802         $sql_extra2 = ((($sort_type > 0) && ($sort_type <= CONTACT_IS_FRIEND)) ? sprintf(" AND `rel` = %d ",intval($sort_type)) : '');
803
804
805         $r = q("SELECT COUNT(*) AS `total` FROM `contact`
806                 WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 ",
807                 intval($_SESSION['uid']));
808         if (DBM::is_result($r)) {
809                 $a->set_pager_total($r[0]['total']);
810                 $total = $r[0]['total'];
811         }
812
813         $sql_extra3 = unavailable_networks();
814
815         $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT %d , %d ",
816                 intval($_SESSION['uid']),
817                 intval($a->pager['start']),
818                 intval($a->pager['itemspage'])
819         );
820
821         $contacts = array();
822
823         if (DBM::is_result($r)) {
824                 foreach ($r as $rr) {
825                         $contacts[] = _contact_detail_for_template($rr);
826                 }
827         }
828
829         $tpl = get_markup_template("contacts-template.tpl");
830         $o .= replace_macros($tpl, array(
831                 '$baseurl' => System::baseUrl(),
832                 '$header' => t('Contacts') . (($nets) ? ' - ' . network_to_name($nets) : ''),
833                 '$tabs' => $t,
834                 '$total' => $total,
835                 '$search' => $search_hdr,
836                 '$desc' => t('Search your contacts'),
837                 '$finding' => (($searching) ? sprintf(t('Results for: %s'),$search) : ""),
838                 '$submit' => t('Find'),
839                 '$cmd' => $a->cmd,
840                 '$contacts' => $contacts,
841                 '$contact_drop_confirm' => t('Do you really want to delete this contact?'),
842                 'multiselect' => 1,
843                 '$batch_actions' => array(
844                         'contacts_batch_update' => t('Update'),
845                         'contacts_batch_block' => t('Block')."/".t("Unblock"),
846                         "contacts_batch_ignore" => t('Ignore')."/".t("Unignore"),
847                         "contacts_batch_archive" => t('Archive')."/".t("Unarchive"),
848                         "contacts_batch_drop" => t('Delete'),
849                 ),
850                 '$h_batch_actions' => t('Batch Actions'),
851                 '$paginate' => paginate($a),
852
853         ));
854
855         return $o;
856 }
857
858 /**
859  * @brief List of pages for the Contact TabBar
860  *
861  * Available Pages are 'Status', 'Profile', 'Contacts' and 'Common Friends'
862  *
863  * @param App $a
864  * @param int $contact_id The ID of the contact
865  * @param int $active_tab 1 if tab should be marked as active
866  *
867  * @return array with with contact TabBar data
868  */
869 function contacts_tab($a, $contact_id, $active_tab) {
870         // tabs
871         $tabs = array(
872                 array(
873                         'label'=>t('Status'),
874                         'url' => "contacts/".$contact_id."/posts",
875                         'sel' => (($active_tab == 1)?'active':''),
876                         'title' => t('Status Messages and Posts'),
877                         'id' => 'status-tab',
878                         'accesskey' => 'm',
879                 ),
880                 array(
881                         'label'=>t('Profile'),
882                         'url' => "contacts/".$contact_id,
883                         'sel' => (($active_tab == 2)?'active':''),
884                         'title' => t('Profile Details'),
885                         'id' => 'profile-tab',
886                         'accesskey' => 'o',
887                 )
888         );
889
890         // Show this tab only if there is visible friend list
891         $x = GContact::countAllFriends(local_user(), $contact_id);
892         if ($x)
893                 $tabs[] = array('label'=>t('Contacts'),
894                                 'url' => "allfriends/".$contact_id,
895                                 'sel' => (($active_tab == 3)?'active':''),
896                                 'title' => t('View all contacts'),
897                                 'id' => 'allfriends-tab',
898                                 'accesskey' => 't');
899
900         // Show this tab only if there is visible common friend list
901         $common = GContact::countCommonFriends(local_user(), $contact_id);
902         if ($common)
903                 $tabs[] = array('label'=>t('Common Friends'),
904                                 'url' => "common/loc/".local_user()."/".$contact_id,
905                                 'sel' => (($active_tab == 4)?'active':''),
906                                 'title' => t('View all common friends'),
907                                 'id' => 'common-loc-tab',
908                                 'accesskey' => 'd');
909
910         $tabs[] = array('label' => t('Advanced'),
911                         'url'   => 'crepair/' . $contact_id,
912                         'sel' => (($active_tab == 5)?'active':''),
913                         'title' => t('Advanced Contact Settings'),
914                         'id'    => 'advanced-tab',
915                         'accesskey' => 'r');
916
917         $tab_tpl = get_markup_template('common_tabs.tpl');
918         $tab_str = replace_macros($tab_tpl, array('$tabs' => $tabs));
919
920         return $tab_str;
921 }
922
923 function contact_posts($a, $contact_id) {
924
925         $r = q("SELECT `url` FROM `contact` WHERE `id` = %d", intval($contact_id));
926         if ($r) {
927                 $contact = $r[0];
928                 $a->page['aside'] = "";
929                 profile_load($a, "", 0, Contact::getDetailsByURL($contact["url"]));
930         } else
931                 $profile = "";
932
933         $tab_str = contacts_tab($a, $contact_id, 1);
934
935         $o .= $tab_str;
936
937         $o .= Contact::getPostsFromUrl($contact["url"]);
938
939         return $o;
940 }
941
942 function _contact_detail_for_template($rr){
943
944         switch($rr['rel']) {
945                 case CONTACT_IS_FRIEND:
946                         $dir_icon = 'images/lrarrow.gif';
947                         $alt_text = t('Mutual Friendship');
948                         break;
949                 case  CONTACT_IS_FOLLOWER;
950                         $dir_icon = 'images/larrow.gif';
951                         $alt_text = t('is a fan of yours');
952                         break;
953                 case CONTACT_IS_SHARING;
954                         $dir_icon = 'images/rarrow.gif';
955                         $alt_text = t('you are a fan of');
956                         break;
957                 default:
958                         break;
959         }
960         if(($rr['network'] === NETWORK_DFRN) && ($rr['rel'])) {
961                 $url = "redir/{$rr['id']}";
962                 $sparkle = ' class="sparkle" ';
963         }
964         else {
965                 $url = $rr['url'];
966                 $sparkle = '';
967         }
968
969         return array(
970                 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'),$rr['name'],$rr['url']),
971                 'edit_hover' => t('Edit contact'),
972                 'photo_menu' => Contact::photoMenu($rr),
973                 'id' => $rr['id'],
974                 'alt_text' => $alt_text,
975                 'dir_icon' => $dir_icon,
976                 'thumb' => proxy_url($rr['thumb'], false, PROXY_SIZE_THUMB),
977                 'name' => htmlentities($rr['name']),
978                 'username' => htmlentities($rr['name']),
979                 'account_type' => Contact::getAccountType($rr),
980                 'sparkle' => $sparkle,
981                 'itemurl' => (($rr['addr'] != "") ? $rr['addr'] : $rr['url']),
982                 'url' => $url,
983                 'network' => network_to_name($rr['network'], $rr['url']),
984         );
985
986 }
987
988 /**
989  * @brief Gives a array with actions which can performed to a given contact
990  *
991  * This includes actions like e.g. 'block', 'hide', 'archive', 'delete' and others
992  *
993  * @param array $contact Data about the Contact
994  * @return array with contact related actions
995  */
996 function contact_actions($contact) {
997
998         $poll_enabled = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_FEED, NETWORK_MAIL));
999         $contact_action = array();
1000
1001         // Provide friend suggestion only for Friendica contacts
1002         if($contact['network'] === NETWORK_DFRN) {
1003                 $contact_actions['suggest'] = array(
1004                                                         'label' => t('Suggest friends'),
1005                                                         'url'   => 'fsuggest/' . $contact['id'],
1006                                                         'title' => '',
1007                                                         'sel'   => '',
1008                                                         'id'    =>  'suggest',
1009                                         );
1010         }
1011
1012         if($poll_enabled) {
1013                 $contact_actions['update'] = array(
1014                                                         'label' => t('Update now'),
1015                                                         'url'   => 'contacts/' . $contact['id'] . '/update',
1016                                                         'title' => '',
1017                                                         'sel'   => '',
1018                                                         'id'    => 'update',
1019                                         );
1020         }
1021
1022         $contact_actions['block'] = array(
1023                                                 'label' => (intval($contact['blocked']) ? t('Unblock') : t('Block') ),
1024                                                 'url'   => 'contacts/' . $contact['id'] . '/block',
1025                                                 'title' => t('Toggle Blocked status'),
1026                                                 'sel'   => (intval($contact['blocked']) ? 'active' : ''),
1027                                                 'id'    => 'toggle-block',
1028                                 );
1029
1030         $contact_actions['ignore'] = array(
1031                                                 'label' => (intval($contact['readonly']) ? t('Unignore') : t('Ignore') ),
1032                                                 'url'   => 'contacts/' . $contact['id'] . '/ignore',
1033                                                 'title' => t('Toggle Ignored status'),
1034                                                 'sel'   => (intval($contact['readonly']) ? 'active' : ''),
1035                                                 'id'    => 'toggle-ignore',
1036                                 );
1037
1038         $contact_actions['archive'] = array(
1039                                                 'label' => (intval($contact['archive']) ? t('Unarchive') : t('Archive') ),
1040                                                 'url'   => 'contacts/' . $contact['id'] . '/archive',
1041                                                 'title' => t('Toggle Archive status'),
1042                                                 'sel'   => (intval($contact['archive']) ? 'active' : ''),
1043                                                 'id'    => 'toggle-archive',
1044                                 );
1045
1046         $contact_actions['delete'] = array(
1047                                                 'label' => t('Delete'),
1048                                                 'url'   => 'contacts/' . $contact['id'] . '/drop',
1049                                                 'title' => t('Delete contact'),
1050                                                 'sel'   => '',
1051                                                 'id'    => 'delete',
1052                                 );
1053
1054         return $contact_actions;
1055 }