diff options
-rwxr-xr-x | include/items.php | 33 | ||||
-rw-r--r-- | include/notifier.php | 24 |
2 files changed, 42 insertions, 15 deletions
diff --git a/include/items.php b/include/items.php index ea46df9bf..12823c6f9 100755 --- a/include/items.php +++ b/include/items.php @@ -18,10 +18,17 @@ function collect_recipients($item,&$private) { require_once('include/group.php'); - if($item['item_private']) - $private = true; + $private = ((intval($item['item_private'])) ? true : false); + $recipients = array(); + + // if the post is marked private but there are no recipients, only add the author and owner + // as recipients. The ACL for the post may live on the hub of a different clone. We need to + // get the post to that hub. if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) { + + // it is private + $allow_people = expand_acl($item['allow_cid']); $allow_groups = expand_groups(expand_acl($item['allow_gid'])); @@ -54,19 +61,19 @@ function collect_recipients($item,&$private) { $private = true; } else { - $recipients = array(); - $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d) and not (abook_flags & %d) and not (abook_flags & %d)", - intval($item['uid']), - intval(ABOOK_FLAG_SELF), - intval(ABOOK_FLAG_PENDING), - intval(ABOOK_FLAG_ARCHIVED) - ); - if($r) { - foreach($r as $rr) { - $recipients[] = $rr['abook_xchan']; + if(! $private) { + $r = q("select abook_xchan from abook where abook_channel = %d and not (abook_flags & %d) and not (abook_flags & %d) and not (abook_flags & %d)", + intval($item['uid']), + intval(ABOOK_FLAG_SELF), + intval(ABOOK_FLAG_PENDING), + intval(ABOOK_FLAG_ARCHIVED) + ); + if($r) { + foreach($r as $rr) { + $recipients[] = $rr['abook_xchan']; + } } } - $private = false; } // This is a somewhat expensive operation but important. diff --git a/include/notifier.php b/include/notifier.php index 0868ac77e..81f971107 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -425,8 +425,28 @@ function notifier_run($argv, $argc){ $sql_extra = (($private) ? "" : " or hubloc_url = '" . dbesc(z_root()) . "' "); - $r = q("select hubloc_sitekey, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") $sql_extra group by hubloc_sitekey"); + + if($relay_to_owner && (! $private) && ($cmd !== 'relay')) { + + // If sending a followup to the post owner, only send it to one channel clone - to avoid race conditions. + // In this case we'll pick the most recently contacted hub, as their primary might be down and the most + // recently contacted has the best chance of being alive. + + // For private posts or uplinks we have to do things differently as only the sending clone will have the recipient list. + // We have to send to all clone channels of the owner to find out who has the definitive list. Posts with + // item_private set (but no ACL list) will return empty recipients (except for the sender and owner) in + // collect_recipients() above. The end result is we should get only one delivery per delivery chain if we + // aren't the owner or author. + + + $r = q("select hubloc_sitekey, hubloc_flags, hubloc_callback, hubloc_host from hubloc + where hubloc_hash in (" . implode(',',$recipients) . ") group by hubloc_sitekey order by hubloc_connected desc limit 1"); + } + else { + $r = q("select hubloc_sitekey, hubloc_flags, hubloc_callback, hubloc_host from hubloc + where hubloc_hash in (" . implode(',',$recipients) . ") $sql_extra group by hubloc_sitekey"); + } + if(! $r) { logger('notifier: no hubs'); return; |