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