diff options
Diffstat (limited to 'mod/acl.php')
-rw-r--r-- | mod/acl.php | 147 |
1 files changed, 72 insertions, 75 deletions
diff --git a/mod/acl.php b/mod/acl.php index 24f2a35e0..8c6eae0b0 100644 --- a/mod/acl.php +++ b/mod/acl.php @@ -13,6 +13,9 @@ function acl_init(&$a){ $type = (x($_REQUEST,'type')?$_REQUEST['type']:""); $noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false); + // List of channels whose connections to also suggest, e.g. currently viewed channel or channels mentioned in a post + $extra_channels = (x($_REQUEST,'extra_channels') ? $_REQUEST['extra_channels'] : array()); + // For use with jquery.autocomplete for private mail completion if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) { @@ -21,9 +24,8 @@ function acl_init(&$a){ $search = $_REQUEST['query']; } - if(!(local_user())) - if($type != 'x') + if(!($type == 'x' || $type == 'c')) killme(); if ($search != "") { @@ -40,72 +42,6 @@ function acl_init(&$a){ $sql_extra = $sql_extra2 = $sql_extra3 = ""; } - // count groups and contacts - if ($type=='' || $type=='g'){ - $r = q("SELECT COUNT(`id`) AS g FROM `groups` WHERE `deleted` = 0 AND `uid` = %d $sql_extra", - intval(local_user()) - ); - $group_count = (int)$r[0]['g']; - } else { - $group_count = 0; - } - - if ($type=='' || $type=='c'){ - $r = q("SELECT COUNT(abook_id) AS c FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d AND not ( abook_flags & %d )>0 and not (xchan_flags & %d )>0 $sql_extra2" , - intval(local_user()), - intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED), - intval(XCHAN_FLAGS_DELETED) - ); - $contact_count = (int)$r[0]['c']; - - if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_user(),'system','taganyone'))) { - if(((! $r) || (! $r[0]['total'])) && $type == 'c') { - $r = q("SELECT COUNT(xchan_hash) AS c FROM xchan - WHERE not (xchan_flags & %d )>0 $sql_extra2" , - intval(XCHAN_FLAGS_DELETED) - ); - $contact_count = (int)$r[0]['c']; - } - } - - } - - elseif ($type == 'm') { - - // autocomplete for Private Messages - - - $r = q("SELECT count(xchan_hash) as c - FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0) - and not ( xchan_flags & %d )>0 - $sql_extra2 ", - intval(local_user()), - intval(PERMS_W_MAIL), - intval(XCHAN_FLAGS_DELETED) - ); - - if($r) - $contact_count = (int)$r[0]['c']; - - } - elseif (($type == 'a')||($type == 'p')) { - - // autocomplete for Contacts - - $r = q("SELECT COUNT(abook_id) AS c FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d and not ( xchan_flags & %d )>0 $sql_extra2" , - intval(local_user()), - intval(XCHAN_FLAGS_DELETED) - ); - $contact_count = (int)$r[0]['c']; - - } else { - $contact_count = 0; - } - - $tot = $group_count+$contact_count; $groups = array(); $contacts = array(); @@ -142,13 +78,75 @@ function acl_init(&$a){ } if ($type=='' || $type=='c') { - $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags + $extra_channels_sql = ''; + // Only include channels who allow the observer to view their permissions + foreach($extra_channels as $channel) { + if(perm_is_allowed(intval($channel), get_observer_hash(),'view_contacts')) + $extra_channels_sql .= "," . intval($channel); + } + + $extra_channels_sql = substr($extra_channels_sql,1); // Remove initial comma + + // Getting info from the abook is better for local users because it contains info about permissions + if(local_user()) { + if($extra_channels_sql != '') + $extra_channels_sql = " OR (abook_channel IN ($extra_channels_sql)) and not (abook_flags & ". intval(ABOOK_FLAG_HIDDEN) . ') > 0'; + + $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags FROM abook left join xchan on abook_xchan = xchan_hash - WHERE abook_channel = %d AND not ( abook_flags & %d )>0 and not (xchan_flags & %d )>0 $sql_extra2 order by $order_extra2 xchan_name asc" , - intval(local_user()), - intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED), - intval(XCHAN_FLAGS_DELETED) - ); + WHERE (abook_channel = %d $extra_channels_sql) AND not ( abook_flags & %d )>0 and not (xchan_flags & %d )>0 $sql_extra2 order by $order_extra2 xchan_name asc" , + intval(local_user()), + intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED), + intval(XCHAN_FLAGS_DELETED) + ); + } + else { // Visitors + $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags + FROM xchan left join xlink on xlink_link = xchan_hash + WHERE xlink_xchan = '%s' AND NOT (xchan_flags & %d) > 0 $sql_extra2 order by $order_extra2 xchan_name asc" , + dbesc(get_observer_hash()), + intval(XCHAN_FLAGS_DELETED)); + + // Find contacts of extra channels + // This is probably more complicated than it needs to be + if($extra_channels_sql) { + // Build a list of hashes that we got previously so we don't get them again + $known_hashes = array("'".get_observer_hash()."'"); + if($r) + foreach($r as $rr) + $known_hashes[] = "'".$rr['hash']."'"; + $known_hashes_sql = 'AND xchan_hash not in ('.join(',',$known_hashes).')'; + + $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags + FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_channel IN ($extra_channels_sql) $known_hashes_sql AND not ( abook_flags & %d )>0 and not (xchan_flags & %d )>0 $sql_extra2 order by $order_extra2 xchan_name asc" , + intval(ABOOK_FLAG_BLOCKED|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED|ABOOK_FLAG_HIDDEN), + intval(XCHAN_FLAGS_DELETED) + ); + if($r2) + $r = array_merge($r,$r2); + + // Sort accoring to match position, then alphabetically. This could be avoided if the above two SQL queries could be combined into one, and the sorting could be done on the SQl server (like in the case of a local user) + $matchpos = function($x) use($search) { + $namepos = strpos($x['name'],$search); + $nickpos = strpos($x['nick'],$search); + // Use a large position if not found + return min($namepos === false ? 9999 : $namepos, $nickpos === false ? 9999 : $nickpos); + }; + // This could be made simpler if PHP supported stable sorting + usort($r,function($a,$b) use($matchpos) { + $pos1 = $matchpos($a); + $pos2 = $matchpos($b); + if($pos1 == $pos2) { // Order alphabetically if match position is the same + if($a['name'] == $b['name']) + return 0; + else + return ($a['name'] < $b['name']) ? -1 : 1; + } + return ($pos1 < $pos2) ? -1 : 1; + }); + } + } if(intval(get_config('system','taganyone')) || intval(get_pconfig(local_user(),'system','taganyone'))) { if((! $r) && $type == 'c') { $r = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags @@ -266,7 +264,6 @@ function acl_init(&$a){ $items = array_merge($groups, $contacts); $o = array( - 'tot' => $tot, 'start' => $start, 'count' => $count, 'items' => $items, |