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