Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1028 lines
30 KiB

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