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.

672 lines
21 KiB

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
6 years ago
11 years ago
11 years ago
11 years ago
6 years ago
10 years ago
6 years ago
10 years ago
11 years ago
11 years ago
6 years ago
11 years ago
11 years ago
10 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
6 years ago
11 years ago
11 years ago
11 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
11 years ago
6 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. <?php
  2. require_once("boot.php");
  3. require_once('include/queue_fn.php');
  4. require_once('include/html2plain.php');
  5. require_once("include/Scrape.php");
  6. require_once('include/diaspora.php');
  7. require_once("include/ostatus.php");
  8. require_once('include/salmon.php');
  9. /*
  10. * This file was at one time responsible for doing all deliveries, but this caused
  11. * big problems when the process was killed or stalled during the delivery process.
  12. * It now invokes separate queues that are delivering via delivery.php and pubsubpublish.php.
  13. */
  14. /*
  15. * The notifier is typically called with:
  16. *
  17. * proc_run('php', "include/notifier.php", COMMAND, ITEM_ID);
  18. *
  19. * where COMMAND is one of the following:
  20. *
  21. * activity (in diaspora.php, dfrn_confirm.php, profiles.php)
  22. * comment-import (in diaspora.php, items.php)
  23. * comment-new (in item.php)
  24. * drop (in diaspora.php, items.php, photos.php)
  25. * edit_post (in item.php)
  26. * event (in events.php)
  27. * expire (in items.php)
  28. * like (in like.php, poke.php)
  29. * mail (in message.php)
  30. * suggest (in fsuggest.php)
  31. * tag (in photos.php, poke.php, tagger.php)
  32. * tgroup (in items.php)
  33. * wall-new (in photos.php, item.php)
  34. * removeme (in Contact.php)
  35. * relocate (in uimport.php)
  36. *
  37. * and ITEM_ID is the id of the item in the database that needs to be sent to others.
  38. */
  39. function notifier_run(&$argv, &$argc){
  40. global $a, $db;
  41. if(is_null($a)){
  42. $a = new App;
  43. }
  44. if(is_null($db)) {
  45. @include(".htconfig.php");
  46. require_once("include/dba.php");
  47. $db = new dba($db_host, $db_user, $db_pass, $db_data);
  48. unset($db_host, $db_user, $db_pass, $db_data);
  49. }
  50. require_once("include/session.php");
  51. require_once("include/datetime.php");
  52. require_once('include/items.php');
  53. require_once('include/bbcode.php');
  54. require_once('include/email.php');
  55. load_config('config');
  56. load_config('system');
  57. load_hooks();
  58. if($argc < 3)
  59. return;
  60. $a->set_baseurl(get_config('system','url'));
  61. logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
  62. $cmd = $argv[1];
  63. switch($cmd) {
  64. case 'mail':
  65. default:
  66. $item_id = intval($argv[2]);
  67. if(! $item_id){
  68. return;
  69. }
  70. break;
  71. }
  72. $expire = false;
  73. $mail = false;
  74. $fsuggest = false;
  75. $relocate = false;
  76. $top_level = false;
  77. $recipients = array();
  78. $url_recipients = array();
  79. $normal_mode = true;
  80. if($cmd === 'mail') {
  81. $normal_mode = false;
  82. $mail = true;
  83. $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
  84. intval($item_id)
  85. );
  86. if(! count($message)){
  87. return;
  88. }
  89. $uid = $message[0]['uid'];
  90. $recipients[] = $message[0]['contact-id'];
  91. $item = $message[0];
  92. }
  93. elseif($cmd === 'expire') {
  94. $normal_mode = false;
  95. $expire = true;
  96. $items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
  97. AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 10 MINUTE",
  98. intval($item_id)
  99. );
  100. $uid = $item_id;
  101. $item_id = 0;
  102. if(! count($items))
  103. return;
  104. }
  105. elseif($cmd === 'suggest') {
  106. $normal_mode = false;
  107. $fsuggest = true;
  108. $suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1",
  109. intval($item_id)
  110. );
  111. if(! count($suggest))
  112. return;
  113. $uid = $suggest[0]['uid'];
  114. $recipients[] = $suggest[0]['cid'];
  115. $item = $suggest[0];
  116. } elseif($cmd === 'removeme') {
  117. $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($item_id));
  118. if (! $r)
  119. return;
  120. $user = $r[0];
  121. $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($item_id));
  122. if (! $r)
  123. return;
  124. $self = $r[0];
  125. $r = q("SELECT * FROM `contact` WHERE `self` = 0 AND `uid` = %d", intval($item_id));
  126. if(! $r)
  127. return;
  128. require_once('include/Contact.php');
  129. foreach($r as $contact) {
  130. terminate_friendship($user, $self, $contact);
  131. }
  132. return;
  133. } elseif($cmd === 'relocate') {
  134. $normal_mode = false;
  135. $relocate = true;
  136. $uid = $item_id;
  137. $recipients_relocate = q("SELECT * FROM contact WHERE uid = %d AND self = 0 AND network = '%s'" , intval($uid), NETWORK_DFRN);
  138. } else {
  139. // find ancestors
  140. $r = q("SELECT * FROM `item` WHERE `id` = %d and visible = 1 and moderated = 0 LIMIT 1",
  141. intval($item_id)
  142. );
  143. if((! count($r)) || (! intval($r[0]['parent']))) {
  144. return;
  145. }
  146. $target_item = $r[0];
  147. $parent_id = intval($r[0]['parent']);
  148. $uid = $r[0]['uid'];
  149. $updated = $r[0]['edited'];
  150. $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
  151. FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d and visible = 1 and moderated = 0 ORDER BY `id` ASC",
  152. intval($parent_id)
  153. );
  154. if(! count($items)) {
  155. return;
  156. }
  157. // avoid race condition with deleting entries
  158. if($items[0]['deleted']) {
  159. foreach($items as $item)
  160. $item['deleted'] = 1;
  161. }
  162. if((count($items) == 1) && ($items[0]['id'] === $target_item['id']) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
  163. logger('notifier: top level post');
  164. $top_level = true;
  165. }
  166. }
  167. $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
  168. `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
  169. `user`.`page-flags`, `user`.`prvnets`
  170. FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
  171. WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
  172. intval($uid)
  173. );
  174. if(! count($r))
  175. return;
  176. $owner = $r[0];
  177. $walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
  178. $hub = get_config('system','huburl');
  179. // If this is a public conversation, notify the feed hub
  180. $public_message = true;
  181. // Do a PuSH
  182. $push_notify = false;
  183. // fill this in with a single salmon slap if applicable
  184. $slap = '';
  185. if(! ($mail || $fsuggest || $relocate)) {
  186. $slap = ostatus::salmon($target_item,$owner);
  187. require_once('include/group.php');
  188. $parent = $items[0];
  189. $thr_parent = q("SELECT `network`, `author-link`, `owner-link` FROM `item` WHERE `uri` = '%s' AND `uid` = %d",
  190. dbesc($target_item["thr-parent"]), intval($target_item["uid"]));
  191. logger('Parent is '.$parent['network'].'. Thread parent is '.$thr_parent[0]['network'], LOGGER_DEBUG);
  192. // This is IMPORTANT!!!!
  193. // We will only send a "notify owner to relay" or followup message if the referenced post
  194. // originated on our system by virtue of having our hostname somewhere
  195. // in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
  196. // if $parent['wall'] == 1 we will already have the parent message in our array
  197. // and we will relay the whole lot.
  198. // expire sends an entire group of expire messages and cannot be forwarded.
  199. // However the conversation owner will be a part of the conversation and will
  200. // be notified during this run.
  201. // Other DFRN conversation members will be alerted during polled updates.
  202. // Diaspora members currently are not notified of expirations, and other networks have
  203. // either limited or no ability to process deletions. We should at least fix Diaspora
  204. // by stringing togther an array of retractions and sending them onward.
  205. $localhost = str_replace('www.','',$a->get_hostname());
  206. if(strpos($localhost,':'))
  207. $localhost = substr($localhost,0,strpos($localhost,':'));
  208. /**
  209. *
  210. * Be VERY CAREFUL if you make any changes to the following several lines. Seemingly innocuous changes
  211. * have been known to cause runaway conditions which affected several servers, along with
  212. * permissions issues.
  213. *
  214. */
  215. $relay_to_owner = false;
  216. if(!$top_level && ($parent['wall'] == 0) && !$expire && (stristr($target_item['uri'],$localhost))) {
  217. $relay_to_owner = true;
  218. }
  219. if(($cmd === 'uplink') && (intval($parent['forum_mode']) == 1) && !$top_level) {
  220. $relay_to_owner = true;
  221. }
  222. // until the 'origin' flag has been in use for several months
  223. // we will just use it as a fallback test
  224. // later we will be able to use it as the primary test of whether or not to relay.
  225. if(! $target_item['origin'])
  226. $relay_to_owner = false;
  227. if($parent['origin'])
  228. $relay_to_owner = false;
  229. if($relay_to_owner) {
  230. logger('notifier: followup '.$target_item["guid"], LOGGER_DEBUG);
  231. // local followup to remote post
  232. $followup = true;
  233. $public_message = false; // not public
  234. $conversant_str = dbesc($parent['contact-id']);
  235. $recipients = array($parent['contact-id']);
  236. $recipients_followup = array($parent['contact-id']);
  237. //if (!$target_item['private'] AND $target_item['wall'] AND
  238. if (!$target_item['private'] AND
  239. (strlen($target_item['allow_cid'].$target_item['allow_gid'].
  240. $target_item['deny_cid'].$target_item['deny_gid']) == 0))
  241. $push_notify = true;
  242. if (($thr_parent AND ($thr_parent[0]['network'] == NETWORK_OSTATUS)) OR ($parent['network'] == NETWORK_OSTATUS)) {
  243. $push_notify = true;
  244. if ($parent["network"] == NETWORK_OSTATUS) {
  245. // Distribute the message to the DFRN contacts as if this wasn't a followup since OStatus can't relay comments
  246. // Currently it is work at progress
  247. $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s' AND NOT `blocked` AND NOT `pending` AND NOT `archive`",
  248. intval($uid),
  249. dbesc(NETWORK_DFRN)
  250. );
  251. if(count($r))
  252. foreach($r as $rr)
  253. $recipients_followup[] = $rr['id'];
  254. }
  255. }
  256. logger("Notify ".$target_item["guid"]." via PuSH: ".($push_notify?"Yes":"No"), LOGGER_DEBUG);
  257. } else {
  258. $followup = false;
  259. logger('Distributing directly '.$target_item["guid"], LOGGER_DEBUG);
  260. // don't send deletions onward for other people's stuff
  261. if($target_item['deleted'] && (! intval($target_item['wall']))) {
  262. logger('notifier: ignoring delete notification for non-wall item');
  263. return;
  264. }
  265. if((strlen($parent['allow_cid']))
  266. || (strlen($parent['allow_gid']))
  267. || (strlen($parent['deny_cid']))
  268. || (strlen($parent['deny_gid']))) {
  269. $public_message = false; // private recipients, not public
  270. }
  271. $allow_people = expand_acl($parent['allow_cid']);
  272. $allow_groups = expand_groups(expand_acl($parent['allow_gid']),true);
  273. $deny_people = expand_acl($parent['deny_cid']);
  274. $deny_groups = expand_groups(expand_acl($parent['deny_gid']));
  275. // if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
  276. // a delivery fork. private groups (forum_mode == 2) do not uplink
  277. if((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
  278. proc_run('php','include/notifier.php','uplink',$item_id);
  279. }
  280. $conversants = array();
  281. foreach($items as $item) {
  282. $recipients[] = $item['contact-id'];
  283. $conversants[] = $item['contact-id'];
  284. // pull out additional tagged people to notify (if public message)
  285. if($public_message && strlen($item['inform'])) {
  286. $people = explode(',',$item['inform']);
  287. foreach($people as $person) {
  288. if(substr($person,0,4) === 'cid:') {
  289. $recipients[] = intval(substr($person,4));
  290. $conversants[] = intval(substr($person,4));
  291. }
  292. else {
  293. $url_recipients[] = substr($person,4);
  294. }
  295. }
  296. }
  297. }
  298. if (count($url_recipients))
  299. logger('notifier: '.$target_item["guid"].' url_recipients ' . print_r($url_recipients,true));
  300. $conversants = array_unique($conversants);
  301. $recipients = array_unique(array_merge($recipients,$allow_people,$allow_groups));
  302. $deny = array_unique(array_merge($deny_people,$deny_groups));
  303. $recipients = array_diff($recipients,$deny);
  304. $conversant_str = dbesc(implode(', ',$conversants));
  305. }
  306. // If the thread parent is OStatus then do some magic to distribute the messages.
  307. // We have not only to look at the parent, since it could be a Friendica thread.
  308. if (($thr_parent AND ($thr_parent[0]['network'] == NETWORK_OSTATUS)) OR ($parent['network'] == NETWORK_OSTATUS)) {
  309. logger('Some parent is OStatus for '.$target_item["guid"]." - Author: ".$thr_parent[0]['author-link']." - Owner: ".$thr_parent[0]['owner-link'], LOGGER_DEBUG);
  310. // Send a salmon to the parent author
  311. $r = q("SELECT `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
  312. dbesc(normalise_link($thr_parent[0]['author-link'])),
  313. intval($uid));
  314. if ($r)
  315. $probed_contact = $r[0];
  316. else
  317. $probed_contact = probe_url($thr_parent[0]['author-link']);
  318. if ($probed_contact["notify"] != "") {
  319. logger('Notify parent author '.$probed_contact["url"].': '.$probed_contact["notify"]);
  320. $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
  321. }
  322. // Send a salmon to the parent owner
  323. $r = q("SELECT `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
  324. dbesc(normalise_link($thr_parent[0]['owner-link'])),
  325. intval($uid));
  326. if ($r)
  327. $probed_contact = $r[0];
  328. else
  329. $probed_contact = probe_url($thr_parent[0]['owner-link']);
  330. if ($probed_contact["notify"] != "") {
  331. logger('Notify parent owner '.$probed_contact["url"].': '.$probed_contact["notify"]);
  332. $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
  333. }
  334. // Send a salmon notification to every person we mentioned in the post
  335. $arr = explode(',',$target_item['tag']);
  336. foreach($arr as $x) {
  337. //logger('Checking tag '.$x, LOGGER_DEBUG);
  338. $matches = null;
  339. if(preg_match('/@\[url=([^\]]*)\]/',$x,$matches)) {
  340. $probed_contact = probe_url($matches[1]);
  341. if ($probed_contact["notify"] != "") {
  342. logger('Notify mentioned user '.$probed_contact["url"].': '.$probed_contact["notify"]);
  343. $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
  344. }
  345. }
  346. }
  347. // It only makes sense to distribute answers to OStatus messages to Friendica and OStatus - but not Diaspora
  348. $sql_extra = " AND `network` IN ('".NETWORK_OSTATUS."', '".NETWORK_DFRN."')";
  349. } else
  350. $sql_extra = " AND `network` IN ('".NETWORK_OSTATUS."', '".NETWORK_DFRN."', '".NETWORK_DIASPORA."', '".NETWORK_MAIL."', '".NETWORK_MAIL2."')";
  351. $r = q("SELECT * FROM `contact` WHERE `id` IN ($conversant_str) AND NOT `blocked` AND NOT `pending` AND NOT `archive`".$sql_extra);
  352. if(count($r))
  353. $contacts = $r;
  354. } else
  355. $public_message = false;
  356. // If this is a public message and pubmail is set on the parent, include all your email contacts
  357. $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
  358. if(! $mail_disabled) {
  359. if((! strlen($target_item['allow_cid'])) && (! strlen($target_item['allow_gid']))
  360. && (! strlen($target_item['deny_cid'])) && (! strlen($target_item['deny_gid']))
  361. && (intval($target_item['pubmail']))) {
  362. $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s'",
  363. intval($uid),
  364. dbesc(NETWORK_MAIL)
  365. );
  366. if(count($r)) {
  367. foreach($r as $rr)
  368. $recipients[] = $rr['id'];
  369. }
  370. }
  371. }
  372. if($followup)
  373. $recip_str = implode(', ', $recipients_followup);
  374. else
  375. $recip_str = implode(', ', $recipients);
  376. if ($relocate)
  377. $r = $recipients_relocate;
  378. else
  379. $r = q("SELECT * FROM `contact` WHERE `id` IN (%s) AND NOT `blocked` AND NOT `pending` AND NOT `archive`",
  380. dbesc($recip_str)
  381. );
  382. $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
  383. // If we are using the worker we don't need a delivery interval
  384. if (get_config("system", "worker"))
  385. $interval = false;
  386. // delivery loop
  387. if(count($r)) {
  388. foreach($r as $contact) {
  389. if(!$contact['self']) {
  390. if(($contact['network'] === NETWORK_DIASPORA) && ($public_message))
  391. continue;
  392. q("INSERT INTO `deliverq` (`cmd`,`item`,`contact`) VALUES ('%s', %d, %d)",
  393. dbesc($cmd),
  394. intval($item_id),
  395. intval($contact['id'])
  396. );
  397. }
  398. }
  399. // This controls the number of deliveries to execute with each separate delivery process.
  400. // By default we'll perform one delivery per process. Assuming a hostile shared hosting
  401. // provider, this provides the greatest chance of deliveries if processes start getting
  402. // killed. We can also space them out with the delivery_interval to also help avoid them
  403. // getting whacked.
  404. // If $deliveries_per_process > 1, we will chain this number of multiple deliveries
  405. // together into a single process. This will reduce the overall number of processes
  406. // spawned for each delivery, but they will run longer.
  407. // When using the workerqueue, we don't need this functionality.
  408. $deliveries_per_process = intval(get_config('system','delivery_batch_count'));
  409. if (($deliveries_per_process <= 0) OR get_config("system", "worker"))
  410. $deliveries_per_process = 1;
  411. $this_batch = array();
  412. for($x = 0; $x < count($r); $x ++) {
  413. $contact = $r[$x];
  414. if($contact['self'])
  415. continue;
  416. logger("Deliver ".$target_item["guid"]." to ".$contact['url']." via network ".$contact['network'], LOGGER_DEBUG);
  417. // potentially more than one recipient. Start a new process and space them out a bit.
  418. // we will deliver single recipient types of message and email recipients here.
  419. $this_batch[] = $contact['id'];
  420. if(count($this_batch) >= $deliveries_per_process) {
  421. proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
  422. $this_batch = array();
  423. if($interval)
  424. @time_sleep_until(microtime(true) + (float) $interval);
  425. }
  426. continue;
  427. }
  428. // be sure to pick up any stragglers
  429. if(count($this_batch))
  430. proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
  431. }
  432. // send salmon slaps to mentioned remote tags (@foo@example.com) in OStatus posts
  433. // They are especially used for notifications to OStatus users that don't follow us.
  434. if($slap && count($url_recipients) && ($public_message || $push_notify) && $normal_mode) {
  435. if(!get_config('system','dfrn_only')) {
  436. foreach($url_recipients as $url) {
  437. if($url) {
  438. logger('notifier: urldelivery: ' . $url);
  439. $deliver_status = slapper($owner,$url,$slap);
  440. /// @TODO Redeliver/queue these items on failure, though there is no contact record
  441. }
  442. }
  443. }
  444. }
  445. if($public_message) {
  446. if (!$followup)
  447. $r0 = diaspora::relay_list();
  448. else
  449. $r0 = array();
  450. $r1 = q("SELECT DISTINCT(`batch`), `id`, `name`,`network` FROM `contact` WHERE `network` = '%s'
  451. AND `uid` = %d AND `rel` != %d group by `batch` ORDER BY rand() ",
  452. dbesc(NETWORK_DIASPORA),
  453. intval($owner['uid']),
  454. intval(CONTACT_IS_SHARING)
  455. );
  456. $r2 = q("SELECT `id`, `name`,`network` FROM `contact`
  457. WHERE `network` in ( '%s', '%s') AND `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `archive`
  458. AND `rel` != %d order by rand() ",
  459. dbesc(NETWORK_DFRN),
  460. dbesc(NETWORK_MAIL2),
  461. intval($owner['uid']),
  462. intval(CONTACT_IS_SHARING)
  463. );
  464. $r = array_merge($r2,$r1,$r0);
  465. if(count($r)) {
  466. logger('pubdeliver '.$target_item["guid"].': '.print_r($r,true), LOGGER_DEBUG);
  467. // throw everything into the queue in case we get killed
  468. foreach($r as $rr) {
  469. if((! $mail) && (! $fsuggest) && (! $followup)) {
  470. q("insert into deliverq ( `cmd`,`item`,`contact` ) values ('%s', %d, %d )",
  471. dbesc($cmd),
  472. intval($item_id),
  473. intval($rr['id'])
  474. );
  475. }
  476. }
  477. foreach($r as $rr) {
  478. // except for Diaspora batch jobs
  479. // Don't deliver to folks who have already been delivered to
  480. if(($rr['network'] !== NETWORK_DIASPORA) && (in_array($rr['id'],$conversants))) {
  481. logger('notifier: already delivered id=' . $rr['id']);
  482. continue;
  483. }
  484. if((! $mail) && (! $fsuggest) && (! $followup)) {
  485. logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]);
  486. proc_run('php','include/delivery.php',$cmd,$item_id,$rr['id']);
  487. if($interval)
  488. @time_sleep_until(microtime(true) + (float) $interval);
  489. }
  490. }
  491. }
  492. $push_notify = true;
  493. }
  494. // Notify PuSH subscribers (Used for OStatus distribution of regular posts)
  495. if($push_notify AND strlen($hub)) {
  496. $hubs = explode(',', $hub);
  497. if(count($hubs)) {
  498. foreach($hubs as $h) {
  499. $h = trim($h);
  500. if(! strlen($h))
  501. continue;
  502. if ($h === '[internal]') {
  503. // Set push flag for PuSH subscribers to this topic,
  504. // they will be notified in queue.php
  505. q("UPDATE `push_subscriber` SET `push` = 1 " .
  506. "WHERE `nickname` = '%s'", dbesc($owner['nickname']));
  507. logger('Activating internal PuSH for item '.$item_id, LOGGER_DEBUG);
  508. } else {
  509. $params = 'hub.mode=publish&hub.url=' . urlencode( $a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] );
  510. post_url($h,$params);
  511. logger('publish for item '.$item_id.' ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code());
  512. }
  513. if(count($hubs) > 1)
  514. sleep(7); // try and avoid multiple hubs responding at precisely the same time
  515. }
  516. }
  517. // Handling the pubsubhubbub requests
  518. proc_run('php','include/pubsubpublish.php');
  519. }
  520. logger('notifier: calling hooks', LOGGER_DEBUG);
  521. if($normal_mode)
  522. call_hooks('notifier_normal',$target_item);
  523. call_hooks('notifier_end',$target_item);
  524. return;
  525. }
  526. if (array_search(__file__,get_included_files())===0){
  527. notifier_run($_SERVER["argv"],$_SERVER["argc"]);
  528. killme();
  529. }