X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fnotifier.php;h=7b645844f6985ca4722d834d1e7a8343a57d1424;hb=a775474dff73e0e17e95bcfee42caeecdacf5295;hp=a71da853db977f1a5725759b96d9c5231c880b13;hpb=c26463b65b4b98f9aca77781fd74a7fe99f73814;p=friendica.git diff --git a/include/notifier.php b/include/notifier.php index a71da853db..7b645844f6 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -20,6 +20,11 @@ function notifier_run($argv, $argc){ require_once('include/items.php'); require_once('include/bbcode.php'); + load_config('config'); + load_config('system'); + + load_hooks(); + if($argc < 3) return; @@ -40,11 +45,15 @@ function notifier_run($argv, $argc){ break; } + $expire = false; + $top_level = false; $recipients = array(); $url_recipients = array(); - if($cmd === 'mail') { + $normal_mode = true; + if($cmd === 'mail') { + $normal_mode = false; $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1", intval($item_id) ); @@ -56,10 +65,33 @@ function notifier_run($argv, $argc){ $item = $message[0]; } + elseif($cmd === 'expire') { + $normal_mode = false; + $expire = true; + $items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1 + AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP - INTERVAL 10 MINUTE", + intval($item_id) + ); + $uid = $item_id; + $item_id = 0; + if(! count($items)) + return; + } + elseif($cmd === 'suggest') { + $normal_mode = false; + $suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1", + intval($item_id) + ); + if(! count($suggest)) + return; + $uid = $suggest[0]['uid']; + $recipients[] = $suggest[0]['cid']; + $item = $suggest[0]; + } else { // find ancestors - $r = q("SELECT `parent`, `uid`, `edited` FROM `item` WHERE `id` = %d LIMIT 1", + $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($item_id) ); @@ -67,6 +99,7 @@ function notifier_run($argv, $argc){ return; } + $target_item = $r[0]; $parent_id = intval($r[0]['parent']); $uid = $r[0]['uid']; $updated = $r[0]['edited']; @@ -75,7 +108,7 @@ function notifier_run($argv, $argc){ intval($parent_id) ); - if(! count($items)){ + if(! count($items)) { return; } @@ -84,38 +117,73 @@ function notifier_run($argv, $argc){ if($items[0]['deleted']) { foreach($items as $item) $item['deleted'] = 1; + } + if(count($items) == 1 && $items[0]['uri'] === $items[0]['parent-uri']) + $top_level = true; } - $r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, `user`.`page-flags` + $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`, + `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, + `user`.`page-flags`, `user`.`prvnets` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1", intval($uid) ); - if(count($r)) - $owner = $r[0]; - else { + if(! count($r)) return; - } + + $owner = $r[0]; + $hub = get_config('system','huburl'); // If this is a public conversation, notify the feed hub - $notify_hub = true; + $public_message = true; // fill this in with a single salmon slap if applicable $slap = ''; - if($cmd != 'mail') { + if($cmd != 'mail' && $cmd != 'suggest') { require_once('include/group.php'); $parent = $items[0]; - if($parent['type'] === 'remote') { + // This is IMPORTANT!!!! + + // We will only send a "notify owner to relay" or followup message if the referenced post + // originated on our system by virtue of having our hostname somewhere + // in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere. + // if $parent['wall'] == 1 we will already have the parent message in our array + // and we will relay the whole lot. + + // expire sends an entire group of expire messages and cannot be forwarded. + // However the conversation owner will be a part of the conversation and will + // be notified during this run. + // Other DFRN conversation members will be alerted during polled updates. + + // Diaspora members currently are not notified of expirations, and other networks have + // either limited or no ability to process deletions. We should at least fix Diaspora + // by stringing togther an array of retractions and sending them onward. + + + $localhost = $a->get_hostname(); + if(strpos($localhost,':')) + $localhost = substr($localhost,0,strpos($localhost,':')); + + /** + * + * Be VERY CAREFUL if you make any changes to the following line. Seemingly innocuous changes + * have been known to cause runaway conditions which affected several servers, along with + * permissions issues. + * + */ + + if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) { // local followup to remote post $followup = true; - $notify_hub = false; // not public + $public_message = false; // not public $conversant_str = dbesc($parent['contact-id']); } else { @@ -125,7 +193,7 @@ function notifier_run($argv, $argc){ || (strlen($parent['allow_gid'])) || (strlen($parent['deny_cid'])) || (strlen($parent['deny_gid']))) { - $notify_hub = false; // private recipients, not public + $public_message = false; // private recipients, not public } $allow_people = expand_acl($parent['allow_cid']); @@ -139,7 +207,7 @@ function notifier_run($argv, $argc){ $recipients[] = $item['contact-id']; $conversants[] = $item['contact-id']; // pull out additional tagged people to notify (if public message) - if($notify_hub && strlen($item['inform'])) { + if($public_message && strlen($item['inform'])) { $people = explode(',',$item['inform']); foreach($people as $person) { if(substr($person,0,4) === 'cid:') { @@ -167,32 +235,23 @@ function notifier_run($argv, $argc){ $r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0"); -// if( ! count($r)){ -// return; -// } if(count($r)) $contacts = $r; } - $feed_template = load_view_file('view/atom_feed.tpl'); - $mail_template = load_view_file('view/atom_mail.tpl'); + $feed_template = get_markup_template('atom_feed.tpl'); + $mail_template = get_markup_template('atom_mail.tpl'); $atom = ''; - $hubxml = ''; $slaps = array(); - if(strlen($hub)) { - $hubs = explode(',', $hub); - if(count($hubs)) { - foreach($hubs as $h) { - $h = trim($h); - if(! strlen($h)) - continue; - $hubxml .= '' . "\n" ; - } - } - } + $hubxml = feed_hublinks(); + + $birthday = feed_birthday($owner['uid'],$owner['timezone']); + + if(strlen($birthday)) + $birthday = '' . xmlify($birthday) . ''; $atom .= replace_macros($feed_template, array( '$version' => xmlify(FRIENDIKA_VERSION), @@ -208,11 +267,13 @@ function notifier_run($argv, $argc){ '$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) , '$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) , '$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) , - '$birthday' => '' + '$birthday' => $birthday )); if($cmd === 'mail') { - $notify_hub = false; // mail is not public + $public_message = false; // mail is not public + + $body = fix_private_photos($item['body'],$owner['uid']); $atom .= replace_macros($mail_template, array( '$name' => xmlify($owner['name']), @@ -221,10 +282,30 @@ function notifier_run($argv, $argc){ '$item_id' => xmlify($item['uri']), '$subject' => xmlify($item['title']), '$created' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00' , ATOM_TIME)), - '$content' => xmlify($item['body']), + '$content' => xmlify($body), '$parent_id' => xmlify($item['parent-uri']) )); } + elseif($cmd === 'suggest') { + $public_message = false; // suggestions are not public + + $sugg_template = get_markup_template('atom_suggest.tpl'); + + $atom .= replace_macros($sugg_template, array( + '$name' => xmlify($item['name']), + '$url' => xmlify($item['url']), + '$photo' => xmlify($item['photo']), + '$request' => xmlify($item['request']), + '$note' => xmlify($item['note']) + )); + + // We don't need this any more + + q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1", + intval($item['id']) + ); + + } else { if($followup) { foreach($items as $item) { // there is only one item @@ -239,21 +320,23 @@ function notifier_run($argv, $argc){ } else { foreach($items as $item) { + if(! $item['parent']) continue; + // private emails may be in included in public conversations. Filter them. + + if(($public_message) && $item['private']) + continue; + $contact = get_item_contact($item,$contacts); if(! $contact) continue; - $atom .= atom_entry($item,'text',$contact,$owner,true); + $atom .= atom_entry($item,'text',$contact,$owner,true); - // There's a problem here - we *were* going to use salmon to provide semi-authenticated - // communication to OStatus, but unless we're the item author they won't verify. - // commented out for now, though we'll still send local replies (and any mentions - // that they contain) upstream. Rethinking the problem space. - -// $slaps[] = atom_entry($item,'html',$contact,$owner,true); + if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire)) + $slaps[] = atom_entry($item,'html',$contact,$owner,true); } } } @@ -261,14 +344,32 @@ function notifier_run($argv, $argc){ logger('notifier: ' . $atom, LOGGER_DATA); -// logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA); + logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA); + + // If this is a public message and pubmail is set on the parent, include all your email contacts + + $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1); + + if(! $mail_disabled) { + if((! strlen($target_item['allow_cid'])) && (! strlen($target_item['allow_gid'])) + && (! strlen($target_item['deny_cid'])) && (! strlen($target_item['deny_gid'])) + && (intval($target_item['pubmail']))) { + $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `network` = '%s'", + intval($uid), + dbesc(NETWORK_MAIL) + ); + if(count($r)) { + foreach($r as $rr) + $recipients[] = $rr['id']; + } + } + } if($followup) $recip_str = $parent['contact-id']; else $recip_str = implode(', ', $recipients); - $r = q("SELECT * FROM `contact` WHERE `id` IN ( %s ) AND `blocked` = 0 AND `pending` = 0 ", dbesc($recip_str) ); @@ -285,7 +386,7 @@ function notifier_run($argv, $argc){ $deliver_status = 0; switch($contact['network']) { - case 'dfrn': + case NETWORK_DFRN: logger('notifier: dfrndelivery: ' . $contact['name']); $deliver_status = dfrn_deliver($owner,$contact,$atom); @@ -303,7 +404,14 @@ function notifier_run($argv, $argc){ ); } break; - case 'stat': + case NETWORK_OSTATUS: + + // Do not send to otatus if we are not configured to send to public networks + if($owner['prvnets']) + break; + if(get_config('system','ostatus_disabled') || get_config('system','dfrn_only')) + break; + if($followup && $contact['notify']) { logger('notifier: slapdelivery: ' . $contact['name']); $deliver_status = slapper($owner,$contact['notify'],$slap); @@ -319,15 +427,13 @@ function notifier_run($argv, $argc){ ); } - - } else { // only send salmon if public - e.g. if it's ok to notify // a public hub, it's ok to send a salmon - if(count($slaps) && $notify_hub) { + if((count($slaps)) && ($public_message) && (! $expire)) { logger('notifier: slapdelivery: ' . $contact['name']); foreach($slaps as $slappy) { if($contact['notify']) { @@ -347,9 +453,122 @@ function notifier_run($argv, $argc){ } } break; - case 'mail': - case 'dspr': - case 'feed': + + case NETWORK_MAIL: + + if(get_config('system','dfrn_only')) + break; + + // WARNING: does not currently convert to RFC2047 header encodings, etc. + + $addr = $contact['addr']; + if(! strlen($addr)) + break; + + if($cmd === 'wall-new' || $cmd === 'comment-new') { + + $it = null; + if($cmd === 'wall-new') + $it = $items[0]; + else { + $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($argv[2]), + intval($uid) + ); + if(count($r)) + $it = $r[0]; + } + if(! $it) + break; + + + + $local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", + intval($uid) + ); + if(! count($local_user)) + break; + + $reply_to = ''; + $r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1", + intval($uid) + ); + if($r1 && $r1[0]['reply_to']) + $reply_to = $r1[0]['reply_to']; + + $subject = (($it['title']) ? $it['title'] : t("\x28no subject\x29")) ; + $headers = 'From: ' . $local_user[0]['username'] . ' <' . $local_user[0]['email'] . '>' . "\n"; + + if($reply_to) + $headers .= 'Reply-to: ' . $reply_to . "\n"; + + $headers .= 'Message-id: <' . $it['uri'] . '>' . "\n"; + + if($it['uri'] !== $it['parent-uri']) { + $header .= 'References: <' . $it['parent-uri'] . '>' . "\n"; + if(! strlen($it['title'])) { + $r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1", + dbesc($it['parent-uri']) + ); + if(count($r)) { + $subtitle = $r[0]['title']; + if($subtitle) { + if(strncasecmp($subtitle,'RE:',3)) + $subject = $subtitle; + else + $subject = 'Re: ' . $subtitle; + } + } + } + } + + $headers .= 'MIME-Version: 1.0' . "\n"; + $headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + $headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; + $html = prepare_body($it); + $message = '' . $html . ''; + logger('notifier: email delivery to ' . $addr); + mail($addr, $subject, $message, $headers); + } + break; + case NETWORK_DIASPORA: + require_once('include/diaspora.php'); + if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode)) + break; + + if(! $contact['pubkey']) + break; + + if($target_item['verb'] === ACTIVITY_DISLIKE) { + // unsupported + break; + } + elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) { + // diaspora delete, + diaspora_send_retraction($target_item,$owner,$contact); + break; + } + elseif($followup) { + // send comments, likes and retractions of likes to owner to relay + diaspora_send_followup($target_item,$owner,$contact); + break; + } + elseif($target_item['parent'] != $target_item['id']) { + // we are the relay - send comments, likes and unlikes to our conversants + diaspora_send_relay($target_item,$owner,$contact); + break; + } + elseif($top_level) { + diaspora_send_status($target_item,$owner,$contact); + break; + } + + break; + + case NETWORK_FEED: + case NETWORK_FACEBOOK: + if(get_config('system','dfrn_only')) + break; default: break; } @@ -358,17 +577,19 @@ function notifier_run($argv, $argc){ // send additional slaps to mentioned remote tags (@foo@example.com) - if($slap && count($url_recipients) && $followup && $notify_hub) { - foreach($url_recipients as $url) { - if($url) { - logger('notifier: urldelivery: ' . $url); - $deliver_status = slapper($owner,$url,$slap); - // TODO: redeliver/queue these items on failure, though there is no contact record + if($slap && count($url_recipients) && ($followup || $top_level) && $public_message && (! $expire)) { + if(! get_config('system','dfrn_only')) { + foreach($url_recipients as $url) { + if($url) { + logger('notifier: urldelivery: ' . $url); + $deliver_status = slapper($owner,$url,$slap); + // TODO: redeliver/queue these items on failure, though there is no contact record + } } } } - if((strlen($hub)) && ($notify_hub)) { + if((strlen($hub)) && ($public_message)) { $hubs = explode(',', $hub); if(count($hubs)) { foreach($hubs as $h) { @@ -384,17 +605,17 @@ function notifier_run($argv, $argc){ } } - if($notify_hub) { + if($public_message) { /** * - * If you have less than 150 dfrn friends and it's a public message, - * we'll just go ahead and push them out securely with dfrn/rino. + * If you have less than 999 dfrn friends and it's a public message, + * we'll just go ahead and push them out securely with dfrn/rino or Diaspora. * If you've got more than that, you'll have to rely on PuSH delivery. * */ - $max_allowed = ((get_config('system','maxpubdeliver') === false) ? 150 : intval(get_config('system','maxdeliver'))); + $max_allowed = ((get_config('system','maxpubdeliver') === false) ? 999 : intval(get_config('system','maxpubdeliver'))); /** * @@ -404,31 +625,71 @@ function notifier_run($argv, $argc){ */ $r = q("SELECT `id`, `name` FROM `contact` - WHERE `network` = 'dfrn' AND `uid` = %d AND `blocked` = 0 AND `pending` = 0 + WHERE `network` in ('%s','%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `rel` != %d ", + dbesc(NETWORK_DFRN), + dbesc(NETWORK_DIASPORA), intval($owner['uid']), - intval(REL_FAN) + intval(CONTACT_IS_SHARING) ); if((count($r)) && (($max_allowed == 0) || (count($r) < $max_allowed))) { + logger('pubdeliver: ' . print_r($r,true)); + foreach($r as $rr) { /* Don't deliver to folks who have already been delivered to */ - if(! in_array($rr['id'], $conversants)) { - $n = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", - intval($rr['id']) - ); + if(in_array($rr['id'],$conversants)) + continue; - if(count($n)) { + $n = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", + intval($rr['id']) + ); + + if(count($n)) { + $contact = $n[0]; + switch($contact['network']) { + case NETWORK_DFRN : + logger('notifier: dfrnpubdelivery: ' . $contact['name']); + $deliver_status = dfrn_deliver($owner,$contact,$atom); + break; + case NETWORK_DIASPORA : + require_once('include/diaspora.php'); + if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode)) + break; + + if(! $contact['pubkey']) + break; - logger('notifier: dfrnpubdelivery: ' . $n[0]['name']); - $deliver_status = dfrn_deliver($owner,$n[0],$atom); + if($target_item['verb'] === ACTIVITY_DISLIKE) { + // unsupported + break; + } + elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) { + // diaspora delete, + diaspora_send_retraction($target_item,$owner,$contact); + break; + } + elseif($followup) { + // send comments, likes and retractions of likes to owner to relay + diaspora_send_followup($target_item,$owner,$contact); + break; + } + elseif($target_item['parent'] != $target_item['id']) { + // we are the relay - send comments, likes and unlikes to our conversants + diaspora_send_relay($target_item,$owner,$contact); + break; + } + elseif($top_level) { + diaspora_send_status($target_item,$owner,$contact); + break; + } + default: + break; } } - else - logger('notifier: dfrnpubdelivery: ignoring ' . $rr['name']); } } } @@ -437,7 +698,6 @@ function notifier_run($argv, $argc){ } if (array_search(__file__,get_included_files())===0){ - echo "run!"; notifier_run($argv,$argc); killme(); }