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.

633 lines
17 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. <?php
  2. require_once("include/contact_selectors.php");
  3. require_once("include/features.php");
  4. require_once("mod/proxy.php");
  5. /**
  6. *
  7. */
  8. /**
  9. * @package acl_selectors
  10. */
  11. function group_select($selname,$selclass,$preselected = false,$size = 4) {
  12. $a = get_app();
  13. $o = '';
  14. $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" >\r\n";
  15. $r = q("SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC",
  16. intval(local_user())
  17. );
  18. $arr = array('group' => $r, 'entry' => $o);
  19. // e.g. 'network_pre_group_deny', 'profile_pre_group_allow'
  20. call_hooks($a->module . '_pre_' . $selname, $arr);
  21. if(count($r)) {
  22. foreach($r as $rr) {
  23. if((is_array($preselected)) && in_array($rr['id'], $preselected))
  24. $selected = " selected=\"selected\" ";
  25. else
  26. $selected = '';
  27. $trimmed = mb_substr($rr['name'],0,12);
  28. $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}\" >$trimmed</option>\r\n";
  29. }
  30. }
  31. $o .= "</select>\r\n";
  32. call_hooks($a->module . '_post_' . $selname, $o);
  33. return $o;
  34. }
  35. function contact_selector($selname, $selclass, $preselected = false, $options) {
  36. $a = get_app();
  37. $mutual = false;
  38. $networks = null;
  39. $single = false;
  40. $exclude = false;
  41. $size = 4;
  42. if(is_array($options)) {
  43. if(x($options,'size'))
  44. $size = $options['size'];
  45. if(x($options,'mutual_friends'))
  46. $mutual = true;
  47. if(x($options,'single'))
  48. $single = true;
  49. if(x($options,'multiple'))
  50. $single = false;
  51. if(x($options,'exclude'))
  52. $exclude = $options['exclude'];
  53. if(x($options,'networks')) {
  54. switch($options['networks']) {
  55. case 'DFRN_ONLY':
  56. $networks = array('dfrn');
  57. break;
  58. case 'PRIVATE':
  59. if(is_array($a->user) && $a->user['prvnets'])
  60. $networks = array('dfrn','mail','dspr');
  61. else
  62. $networks = array('dfrn','face','mail', 'dspr');
  63. break;
  64. case 'TWO_WAY':
  65. if(is_array($a->user) && $a->user['prvnets'])
  66. $networks = array('dfrn','mail','dspr');
  67. else
  68. $networks = array('dfrn','face','mail','dspr','stat');
  69. break;
  70. default:
  71. break;
  72. }
  73. }
  74. }
  75. $x = array('options' => $options, 'size' => $size, 'single' => $single, 'mutual' => $mutual, 'exclude' => $exclude, 'networks' => $networks);
  76. call_hooks('contact_select_options', $x);
  77. $o = '';
  78. $sql_extra = '';
  79. if($x['mutual']) {
  80. $sql_extra .= sprintf(" AND `rel` = %d ", intval(CONTACT_IS_FRIEND));
  81. }
  82. if(intval($x['exclude']))
  83. $sql_extra .= sprintf(" AND `id` != %d ", intval($x['exclude']));
  84. if(is_array($x['networks']) && count($x['networks'])) {
  85. for($y = 0; $y < count($x['networks']) ; $y ++)
  86. $x['networks'][$y] = "'" . dbesc($x['networks'][$y]) . "'";
  87. $str_nets = implode(',',$x['networks']);
  88. $sql_extra .= " AND `network` IN ( $str_nets ) ";
  89. }
  90. $tabindex = (x($options, 'tabindex') ? "tabindex=\"" . $options["tabindex"] . "\"" : "");
  91. if($x['single'])
  92. $o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"" . $x['size'] . "\" $tabindex >\r\n";
  93. else
  94. $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"" . $x['size'] . "$\" $tabindex >\r\n";
  95. $r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
  96. WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
  97. $sql_extra
  98. ORDER BY `name` ASC ",
  99. intval(local_user())
  100. );
  101. $arr = array('contact' => $r, 'entry' => $o);
  102. // e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
  103. call_hooks($a->module . '_pre_' . $selname, $arr);
  104. if(count($r)) {
  105. foreach($r as $rr) {
  106. if((is_array($preselected)) && in_array($rr['id'], $preselected))
  107. $selected = " selected=\"selected\" ";
  108. else
  109. $selected = '';
  110. $trimmed = mb_substr($rr['name'],0,20);
  111. $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}|{$rr['url']}\" >$trimmed</option>\r\n";
  112. }
  113. }
  114. $o .= "</select>\r\n";
  115. call_hooks($a->module . '_post_' . $selname, $o);
  116. return $o;
  117. }
  118. function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false, $tabindex = null) {
  119. require_once("include/bbcode.php");
  120. $a = get_app();
  121. $o = '';
  122. // When used for private messages, we limit correspondence to mutual DFRN/Friendica friends and the selector
  123. // to one recipient. By default our selector allows multiple selects amongst all contacts.
  124. $sql_extra = '';
  125. if($privmail || $celeb) {
  126. $sql_extra .= sprintf(" AND `rel` = %d ", intval(CONTACT_IS_FRIEND));
  127. }
  128. if($privmail) {
  129. $sql_extra .= " AND `network` IN ( 'dfrn', 'dspr' ) ";
  130. }
  131. elseif($privatenet) {
  132. $sql_extra .= " AND `network` IN ( 'dfrn', 'mail', 'face', 'dspr' ) ";
  133. }
  134. $tabindex = ($tabindex > 0 ? "tabindex=\"$tabindex\"" : "");
  135. if($privmail)
  136. $o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\" $tabindex >\r\n";
  137. else
  138. $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
  139. $r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
  140. WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
  141. $sql_extra
  142. ORDER BY `name` ASC ",
  143. intval(local_user())
  144. );
  145. $arr = array('contact' => $r, 'entry' => $o);
  146. // e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
  147. call_hooks($a->module . '_pre_' . $selname, $arr);
  148. if(count($r)) {
  149. foreach($r as $rr) {
  150. if((is_array($preselected)) && in_array($rr['id'], $preselected))
  151. $selected = " selected=\"selected\" ";
  152. else
  153. $selected = '';
  154. if($privmail)
  155. $trimmed = GetProfileUsername($rr['url'], $rr['name'], false);
  156. else
  157. $trimmed = mb_substr($rr['name'],0,20);
  158. $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}|{$rr['url']}\" >$trimmed</option>\r\n";
  159. }
  160. }
  161. $o .= "</select>\r\n";
  162. call_hooks($a->module . '_post_' . $selname, $o);
  163. return $o;
  164. }
  165. function fixacl(&$item) {
  166. $item = intval(str_replace(array('<','>'),array('',''),$item));
  167. }
  168. function prune_deadguys($arr) {
  169. if(! $arr)
  170. return $arr;
  171. $str = dbesc(implode(',',$arr));
  172. $r = q("select id from contact where id in ( " . $str . ") and blocked = 0 and pending = 0 and archive = 0 ");
  173. if($r) {
  174. $ret = array();
  175. foreach($r as $rr)
  176. $ret[] = intval($rr['id']);
  177. return $ret;
  178. }
  179. return array();
  180. }
  181. function get_acl_permissions($user = null) {
  182. $allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
  183. if(is_array($user)) {
  184. $allow_cid = ((strlen($user['allow_cid']))
  185. ? explode('><', $user['allow_cid']) : array() );
  186. $allow_gid = ((strlen($user['allow_gid']))
  187. ? explode('><', $user['allow_gid']) : array() );
  188. $deny_cid = ((strlen($user['deny_cid']))
  189. ? explode('><', $user['deny_cid']) : array() );
  190. $deny_gid = ((strlen($user['deny_gid']))
  191. ? explode('><', $user['deny_gid']) : array() );
  192. array_walk($allow_cid,'fixacl');
  193. array_walk($allow_gid,'fixacl');
  194. array_walk($deny_cid,'fixacl');
  195. array_walk($deny_gid,'fixacl');
  196. }
  197. $allow_cid = prune_deadguys($allow_cid);
  198. return array(
  199. 'allow_cid' => $allow_cid,
  200. 'allow_gid' => $allow_gid,
  201. 'deny_cid' => $deny_cid,
  202. 'deny_gid' => $deny_gid,
  203. );
  204. }
  205. function populate_acl($user = null,$celeb = false) {
  206. $perms = get_acl_permissions($user);
  207. // We shouldn't need to prune deadguys from the block list. Either way they can't get the message.
  208. // Also no point enumerating groups and checking them, that will take place on delivery.
  209. // $deny_cid = prune_deadguys($deny_cid);
  210. /*$o = '';
  211. $o .= '<div id="acl-wrapper">';
  212. $o .= '<div id="acl-permit-outer-wrapper">';
  213. $o .= '<div id="acl-permit-text">' . t('Visible To:') . '</div><div id="jot-public">' . t('everybody') . '</div>';
  214. $o .= '<div id="acl-permit-text-end"></div>';
  215. $o .= '<div id="acl-permit-wrapper">';
  216. $o .= '<div id="group_allow_wrapper">';
  217. $o .= '<label id="acl-allow-group-label" for="group_allow" >' . t('Groups') . '</label>';
  218. $o .= group_select('group_allow','group_allow',$allow_gid);
  219. $o .= '</div>';
  220. $o .= '<div id="contact_allow_wrapper">';
  221. $o .= '<label id="acl-allow-contact-label" for="contact_allow" >' . t('Contacts') . '</label>';
  222. $o .= contact_select('contact_allow','contact_allow',$allow_cid,4,false,$celeb,true);
  223. $o .= '</div>';
  224. $o .= '</div>' . "\r\n";
  225. $o .= '<div id="acl-allow-end"></div>' . "\r\n";
  226. $o .= '</div>';
  227. $o .= '<div id="acl-deny-outer-wrapper">';
  228. $o .= '<div id="acl-deny-text">' . t('Except For:') . '</div>';
  229. $o .= '<div id="acl-deny-text-end"></div>';
  230. $o .= '<div id="acl-deny-wrapper">';
  231. $o .= '<div id="group_deny_wrapper" >';
  232. $o .= '<label id="acl-deny-group-label" for="group_deny" >' . t('Groups') . '</label>';
  233. $o .= group_select('group_deny','group_deny', $deny_gid);
  234. $o .= '</div>';
  235. $o .= '<div id="contact_deny_wrapper" >';
  236. $o .= '<label id="acl-deny-contact-label" for="contact_deny" >' . t('Contacts') . '</label>';
  237. $o .= contact_select('contact_deny','contact_deny', $deny_cid,4,false, $celeb,true);
  238. $o .= '</div>';
  239. $o .= '</div>' . "\r\n";
  240. $o .= '<div id="acl-deny-end"></div>' . "\r\n";
  241. $o .= '</div>';
  242. $o .= '</div>' . "\r\n";
  243. $o .= '<div id="acl-wrapper-end"></div>' . "\r\n";*/
  244. $tpl = get_markup_template("acl_selector.tpl");
  245. $o = replace_macros($tpl, array(
  246. '$showall'=> t("Visible to everybody"),
  247. '$show' => t("show"),
  248. '$hide' => t("don't show"),
  249. '$allowcid' => json_encode($perms['allow_cid']),
  250. '$allowgid' => json_encode($perms['allow_gid']),
  251. '$denycid' => json_encode($perms['deny_cid']),
  252. '$denygid' => json_encode($perms['deny_gid']),
  253. '$features' => array(
  254. "aclautomention"=>(feature_enabled($user['uid'],"aclautomention")?"true":"false")
  255. ),
  256. ));
  257. return $o;
  258. }
  259. function construct_acl_data(&$a, $user) {
  260. // Get group and contact information for html ACL selector
  261. $acl_data = acl_lookup($a, 'html');
  262. $user_defaults = get_acl_permissions($user);
  263. if($acl_data['groups']) {
  264. foreach($acl_data['groups'] as $key=>$group) {
  265. // Add a "selected" flag to groups that are posted to by default
  266. if($user_defaults['allow_gid'] &&
  267. in_array($group['id'], $user_defaults['allow_gid']) && !in_array($group['id'], $user_defaults['deny_gid']) )
  268. $acl_data['groups'][$key]['selected'] = 1;
  269. else
  270. $acl_data['groups'][$key]['selected'] = 0;
  271. }
  272. }
  273. if($acl_data['contacts']) {
  274. foreach($acl_data['contacts'] as $key=>$contact) {
  275. // Add a "selected" flag to groups that are posted to by default
  276. if($user_defaults['allow_cid'] &&
  277. in_array($contact['id'], $user_defaults['allow_cid']) && !in_array($contact['id'], $user_defaults['deny_cid']) )
  278. $acl_data['contacts'][$key]['selected'] = 1;
  279. else
  280. $acl_data['contacts'][$key]['selected'] = 0;
  281. }
  282. }
  283. return $acl_data;
  284. }
  285. function acl_lookup(&$a, $out_type = 'json') {
  286. if(!local_user())
  287. return "";
  288. $start = (x($_REQUEST,'start')?$_REQUEST['start']:0);
  289. $count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
  290. $search = (x($_REQUEST,'search')?$_REQUEST['search']:"");
  291. $type = (x($_REQUEST,'type')?$_REQUEST['type']:"");
  292. $conv_id = (x($_REQUEST,'conversation')?$_REQUEST['conversation']:null);
  293. // For use with jquery.autocomplete for private mail completion
  294. if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
  295. if(! $type)
  296. $type = 'm';
  297. $search = $_REQUEST['query'];
  298. }
  299. if ($search!=""){
  300. $sql_extra = "AND `name` LIKE '%%".dbesc($search)."%%'";
  301. $sql_extra2 = "AND (`attag` LIKE '%%".dbesc($search)."%%' OR `name` LIKE '%%".dbesc($search)."%%' OR `nick` LIKE '%%".dbesc($search)."%%')";
  302. } else {
  303. $sql_extra = $sql_extra2 = "";
  304. }
  305. // count groups and contacts
  306. if ($type=='' || $type=='g'){
  307. $r = q("SELECT COUNT(*) AS g FROM `group` WHERE `deleted` = 0 AND `uid` = %d $sql_extra",
  308. intval(local_user())
  309. );
  310. $group_count = (int)$r[0]['g'];
  311. } else {
  312. $group_count = 0;
  313. }
  314. if ($type=='' || $type=='c'){
  315. $r = q("SELECT COUNT(*) AS c FROM `contact`
  316. WHERE `uid` = %d AND `self` = 0
  317. AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
  318. AND `notify` != '' $sql_extra2" ,
  319. intval(local_user())
  320. );
  321. $contact_count = (int)$r[0]['c'];
  322. }
  323. elseif ($type == 'm') {
  324. // autocomplete for Private Messages
  325. $r = q("SELECT COUNT(*) AS c FROM `contact`
  326. WHERE `uid` = %d AND `self` = 0
  327. AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
  328. AND `network` IN ('%s','%s','%s') $sql_extra2" ,
  329. intval(local_user()),
  330. dbesc(NETWORK_DFRN),
  331. dbesc(NETWORK_ZOT),
  332. dbesc(NETWORK_DIASPORA)
  333. );
  334. $contact_count = (int)$r[0]['c'];
  335. }
  336. elseif ($type == 'a') {
  337. // autocomplete for Contacts
  338. $r = q("SELECT COUNT(*) AS c FROM `contact`
  339. WHERE `uid` = %d AND `self` = 0
  340. AND `pending` = 0 $sql_extra2" ,
  341. intval(local_user())
  342. );
  343. $contact_count = (int)$r[0]['c'];
  344. } else {
  345. $contact_count = 0;
  346. }
  347. $tot = $group_count+$contact_count;
  348. $groups = array();
  349. $contacts = array();
  350. if ($type=='' || $type=='g'){
  351. $r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') as uids
  352. FROM `group`,`group_member`
  353. WHERE `group`.`deleted` = 0 AND `group`.`uid` = %d
  354. AND `group_member`.`gid`=`group`.`id`
  355. $sql_extra
  356. GROUP BY `group`.`id`
  357. ORDER BY `group`.`name`
  358. LIMIT %d,%d",
  359. intval(local_user()),
  360. intval($start),
  361. intval($count)
  362. );
  363. foreach($r as $g){
  364. // logger('acl: group: ' . $g['name'] . ' members: ' . $g['uids']);
  365. $groups[] = array(
  366. "type" => "g",
  367. "photo" => "images/twopeople.png",
  368. "name" => $g['name'],
  369. "id" => intval($g['id']),
  370. "uids" => array_map("intval", explode(",",$g['uids'])),
  371. "link" => '',
  372. "forum" => '0'
  373. );
  374. }
  375. }
  376. if ($type=='' || $type=='c'){
  377. $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, forum FROM `contact`
  378. WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
  379. $sql_extra2
  380. ORDER BY `name` ASC ",
  381. intval(local_user())
  382. );
  383. }
  384. elseif($type == 'm') {
  385. $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact`
  386. WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
  387. AND `network` IN ('%s','%s','%s')
  388. $sql_extra2
  389. ORDER BY `name` ASC ",
  390. intval(local_user()),
  391. dbesc(NETWORK_DFRN),
  392. dbesc(NETWORK_ZOT),
  393. dbesc(NETWORK_DIASPORA)
  394. );
  395. }
  396. elseif($type == 'a') {
  397. $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact`
  398. WHERE `uid` = %d AND `pending` = 0
  399. $sql_extra2
  400. ORDER BY `name` ASC ",
  401. intval(local_user())
  402. );
  403. }
  404. else
  405. $r = array();
  406. if($type == 'm' || $type == 'a') {
  407. $x = array();
  408. $x['query'] = $search;
  409. $x['photos'] = array();
  410. $x['links'] = array();
  411. $x['suggestions'] = array();
  412. $x['data'] = array();
  413. if(count($r)) {
  414. foreach($r as $g) {
  415. $x['photos'][] = proxy_url($g['micro']);
  416. $x['links'][] = $g['url'];
  417. $x['suggestions'][] = $g['name'];
  418. $x['data'][] = intval($g['id']);
  419. }
  420. }
  421. echo json_encode($x);
  422. killme();
  423. }
  424. if(count($r)) {
  425. foreach($r as $g){
  426. $contacts[] = array(
  427. "type" => "c",
  428. "photo" => proxy_url($g['micro']),
  429. "name" => $g['name'],
  430. "id" => intval($g['id']),
  431. "network" => $g['network'],
  432. "link" => $g['url'],
  433. "nick" => ($g['attag']) ? $g['attag'] : $g['nick'],
  434. "forum" => $g['forum']
  435. );
  436. }
  437. }
  438. $items = array_merge($groups, $contacts);
  439. if ($conv_id) {
  440. /* if $conv_id is set, get unknow contacts in thread */
  441. /* but first get know contacts url to filter them out */
  442. function _contact_link($i){ return dbesc($i['link']); }
  443. $known_contacts = array_map(_contact_link, $contacts);
  444. $unknow_contacts=array();
  445. $r = q("select
  446. `author-avatar`,`author-name`,`author-link`
  447. from item where parent=%d
  448. and (
  449. `author-name` LIKE '%%%s%%' OR
  450. `author-link` LIKE '%%%s%%'
  451. ) and
  452. `author-link` NOT IN ('%s')
  453. GROUP BY `author-link`
  454. ORDER BY `author-name` ASC
  455. ",
  456. intval($conv_id),
  457. dbesc($search),
  458. dbesc($search),
  459. implode("','", $known_contacts)
  460. );
  461. if (is_array($r) && count($r)){
  462. foreach($r as $row) {
  463. // nickname..
  464. $up = parse_url($row['author-link']);
  465. $nick = explode("/",$up['path']);
  466. $nick = $nick[count($nick)-1];
  467. $nick .= "@".$up['host'];
  468. // /nickname
  469. $unknow_contacts[] = array(
  470. "type" => "c",
  471. "photo" => proxy_url($row['author-avatar']),
  472. "name" => $row['author-name'],
  473. "id" => '',
  474. "network" => "unknown",
  475. "link" => $row['author-link'],
  476. "nick" => $nick,
  477. "forum" => false
  478. );
  479. }
  480. }
  481. $items = array_merge($items, $unknow_contacts);
  482. $tot += count($unknow_contacts);
  483. }
  484. if($out_type === 'html') {
  485. $o = array(
  486. 'tot' => $tot,
  487. 'start' => $start,
  488. 'count' => $count,
  489. 'groups' => $groups,
  490. 'contacts' => $contacts,
  491. );
  492. return $o;
  493. }
  494. $o = array(
  495. 'tot' => $tot,
  496. 'start' => $start,
  497. 'count' => $count,
  498. 'items' => $items,
  499. );
  500. echo json_encode($o);
  501. killme();
  502. }