diff options
-rwxr-xr-x | boot.php | 1 | ||||
-rw-r--r-- | mod/acl.php | 127 | ||||
-rw-r--r-- | view/js/autocomplete.js | 16 | ||||
-rwxr-xr-x | view/tpl/head.tpl | 2 | ||||
-rwxr-xr-x | view/tpl/jot-header.tpl | 2 |
5 files changed, 68 insertions, 80 deletions
@@ -1024,6 +1024,7 @@ class App { '$head_js' => head_get_js(), '$js_strings' => js_strings(), '$zid' => get_my_address(), + '$channel_id' => $this->profile['uid'], )) . $this->page['htmlhead']; // always put main.js at the end diff --git a/mod/acl.php b/mod/acl.php index 797a3633b..7973ece4e 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 != "") { @@ -37,72 +39,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(); @@ -139,13 +75,55 @@ 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 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 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 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 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); + } + } 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 @@ -263,7 +241,6 @@ function acl_init(&$a){ $items = array_merge($groups, $contacts); $o = array( - 'tot' => $tot, 'start' => $start, 'count' => $count, 'items' => $items, diff --git a/view/js/autocomplete.js b/view/js/autocomplete.js index 7c3145769..204d3756f 100644 --- a/view/js/autocomplete.js +++ b/view/js/autocomplete.js @@ -3,13 +3,16 @@ * * require jQuery, jquery.textcomplete */ -function mysearch(term, callback, backend_url) { +function mysearch(term, callback, backend_url, extra_channels) { var postdata = { start:0, count:100, search:term, type:'c', } + + if(extra_channels) { + postdata['extra_channels[]'] = extra_channels; $.ajax({ type:'POST', @@ -28,20 +31,25 @@ function format(item) { function replace(item) { // $2 ensures that prefix (@,@!) is preserved - return '$1$2'+item.nick.replace(' ','') + '+' + item.id; + var id = item.id; + // 16 chars of hash should be enough. Full hash could be used if it can be done in a visually appealing way. + // 16 chars is also the minimum length in the backend (otherwise it's interpreted as a local id). + if(id.length > 16) + id = item.id.substring(0,16); + return '$1$2'+item.nick.replace(' ','') + '+' + id; } /** * jQuery plugin 'contact_autocomplete' */ (function( $ ){ - $.fn.contact_autocomplete = function(backend_url) { + $.fn.contact_autocomplete = function(backend_url, extra_channels = null) { // Autocomplete contacts contacts = { match: /(^|\s)(@\!*)([^ \n]+)$/, index: 3, - search: function(term, callback) { mysearch(term, callback, backend_url); }, + search: function(term, callback) { mysearch(term, callback, backend_url, extra_channels); }, replace: replace, template: format, } diff --git a/view/tpl/head.tpl b/view/tpl/head.tpl index 9c9e7b970..8a32bd7f6 100755 --- a/view/tpl/head.tpl +++ b/view/tpl/head.tpl @@ -26,6 +26,8 @@ var localUser = {{if $local_user}}{{$local_user}}{{else}}false{{/if}}; var zid = {{if $zid}}'{{$zid}}'{{else}}null{{/if}}; var justifiedGalleryActive = false; + {{if $channel_hash}}var channelHash = '{{$channel_hash}}';{{/if}} + {{if $channel_id}}var channelId = '{{$channel_id}}';{{/if}}{{* Used in e.g. autocomplete *}} </script> diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl index bdbb7d09c..c23395b03 100755 --- a/view/tpl/jot-header.tpl +++ b/view/tpl/jot-header.tpl @@ -10,7 +10,7 @@ function initEditor(cb){ if(plaintext == 'none') { $("#profile-jot-text-loading").spin(false).hide(); $("#profile-jot-text").css({ 'height': 200, 'color': '#000' }); - $("#profile-jot-text").contact_autocomplete(baseurl+"/acl"); + $("#profile-jot-text").contact_autocomplete(baseurl+"/acl",[channelId]); // Also gives suggestions from current channel's connections editor = true; $("a#jot-perms-icon").colorbox({ 'inline' : true, |