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.

notifier.php 19KB

3 years ago
3 years ago
3 years ago
8 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
3 years ago
3 years ago
10 years ago
10 years ago
10 years ago
10 years ago
4 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
5 years ago
3 years ago
3 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. use Friendica\Core\Config;
  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(PRIORITY_HIGH, "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;
  41. require_once('include/datetime.php');
  42. require_once('include/items.php');
  43. require_once('include/bbcode.php');
  44. require_once('include/email.php');
  45. if ($argc < 3) {
  46. return;
  47. }
  48. logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
  49. $cmd = $argv[1];
  50. switch($cmd) {
  51. case 'mail':
  52. default:
  53. $item_id = intval($argv[2]);
  54. if (! $item_id) {
  55. return;
  56. }
  57. break;
  58. }
  59. $expire = false;
  60. $mail = false;
  61. $fsuggest = false;
  62. $relocate = false;
  63. $top_level = false;
  64. $recipients = array();
  65. $url_recipients = array();
  66. $normal_mode = true;
  67. if ($cmd === 'mail') {
  68. $normal_mode = false;
  69. $mail = true;
  70. $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
  71. intval($item_id)
  72. );
  73. if (! count($message)) {
  74. return;
  75. }
  76. $uid = $message[0]['uid'];
  77. $recipients[] = $message[0]['contact-id'];
  78. $item = $message[0];
  79. } elseif ($cmd === 'expire') {
  80. $normal_mode = false;
  81. $expire = true;
  82. $items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
  83. AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 10 MINUTE",
  84. intval($item_id)
  85. );
  86. $uid = $item_id;
  87. $item_id = 0;
  88. if (! count($items)) {
  89. return;
  90. }
  91. } elseif ($cmd === 'suggest') {
  92. $normal_mode = false;
  93. $fsuggest = true;
  94. $suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1",
  95. intval($item_id)
  96. );
  97. if (! count($suggest)) {
  98. return;
  99. }
  100. $uid = $suggest[0]['uid'];
  101. $recipients[] = $suggest[0]['cid'];
  102. $item = $suggest[0];
  103. } elseif ($cmd === 'removeme') {
  104. $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
  105. `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
  106. `user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`, `user`.`guid`
  107. FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
  108. WHERE `contact`.`uid` = %d AND `contact`.`self` LIMIT 1",
  109. intval($item_id));
  110. if (!$r)
  111. return;
  112. $user = $r[0];
  113. $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($item_id));
  114. if (!$r)
  115. return;
  116. $self = $r[0];
  117. $r = q("SELECT * FROM `contact` WHERE NOT `self` AND `uid` = %d", intval($item_id));
  118. if (!$r) {
  119. return;
  120. }
  121. require_once('include/Contact.php');
  122. foreach ($r as $contact) {
  123. terminate_friendship($user, $self, $contact);
  124. }
  125. return;
  126. } elseif ($cmd === 'relocate') {
  127. $normal_mode = false;
  128. $relocate = true;
  129. $uid = $item_id;
  130. $recipients_relocate = q("SELECT * FROM contact WHERE uid = %d AND self = 0 AND network = '%s'" , intval($uid), NETWORK_DFRN);
  131. } else {
  132. // find ancestors
  133. $r = q("SELECT * FROM `item` WHERE `id` = %d and visible = 1 and moderated = 0 LIMIT 1",
  134. intval($item_id)
  135. );
  136. if ((! dbm::is_result($r)) || (! intval($r[0]['parent']))) {
  137. return;
  138. }
  139. $target_item = $r[0];
  140. $parent_id = intval($r[0]['parent']);
  141. $uid = $r[0]['uid'];
  142. $updated = $r[0]['edited'];
  143. $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
  144. FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d and visible = 1 and moderated = 0 ORDER BY `id` ASC",
  145. intval($parent_id)
  146. );
  147. if (! count($items)) {
  148. return;
  149. }
  150. // avoid race condition with deleting entries
  151. if ($items[0]['deleted']) {
  152. foreach ($items as $item) {
  153. $item['deleted'] = 1;
  154. }
  155. }
  156. if ((count($items) == 1) && ($items[0]['id'] === $target_item['id']) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
  157. logger('notifier: top level post');
  158. $top_level = true;
  159. }
  160. }
  161. $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
  162. `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
  163. `user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`
  164. FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
  165. WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
  166. intval($uid)
  167. );
  168. if (! dbm::is_result($r)) {
  169. return;
  170. }
  171. $owner = $r[0];
  172. $walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
  173. $hub = get_config('system','huburl');
  174. // Should the post be transmitted to Diaspora?
  175. $diaspora_delivery = true;
  176. // If this is a public conversation, notify the feed hub
  177. $public_message = true;
  178. // Do a PuSH
  179. $push_notify = false;
  180. // fill this in with a single salmon slap if applicable
  181. $slap = '';
  182. if (! ($mail || $fsuggest || $relocate)) {
  183. $slap = ostatus::salmon($target_item,$owner);
  184. require_once('include/group.php');
  185. $parent = $items[0];
  186. $thr_parent = q("SELECT `network`, `author-link`, `owner-link` FROM `item` WHERE `uri` = '%s' AND `uid` = %d",
  187. dbesc($target_item["thr-parent"]), intval($target_item["uid"]));
  188. logger('GUID: '.$target_item["guid"].': Parent is '.$parent['network'].'. Thread parent is '.$thr_parent[0]['network'], LOGGER_DEBUG);
  189. // This is IMPORTANT!!!!
  190. // We will only send a "notify owner to relay" or followup message if the referenced post
  191. // originated on our system by virtue of having our hostname somewhere
  192. // in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
  193. // if $parent['wall'] == 1 we will already have the parent message in our array
  194. // and we will relay the whole lot.
  195. // expire sends an entire group of expire messages and cannot be forwarded.
  196. // However the conversation owner will be a part of the conversation and will
  197. // be notified during this run.
  198. // Other DFRN conversation members will be alerted during polled updates.
  199. // Diaspora members currently are not notified of expirations, and other networks have
  200. // either limited or no ability to process deletions. We should at least fix Diaspora
  201. // by stringing togther an array of retractions and sending them onward.
  202. $localhost = str_replace('www.','',$a->get_hostname());
  203. if (strpos($localhost,':')) {
  204. $localhost = substr($localhost,0,strpos($localhost,':'));
  205. }
  206. /**
  207. *
  208. * Be VERY CAREFUL if you make any changes to the following several lines. Seemingly innocuous changes
  209. * have been known to cause runaway conditions which affected several servers, along with
  210. * permissions issues.
  211. *
  212. */
  213. $relay_to_owner = false;
  214. if (!$top_level && ($parent['wall'] == 0) && !$expire && (stristr($target_item['uri'],$localhost))) {
  215. $relay_to_owner = true;
  216. }
  217. if (($cmd === 'uplink') && (intval($parent['forum_mode']) == 1) && !$top_level) {
  218. $relay_to_owner = true;
  219. }
  220. // until the 'origin' flag has been in use for several months
  221. // we will just use it as a fallback test
  222. // later we will be able to use it as the primary test of whether or not to relay.
  223. if (! $target_item['origin']) {
  224. $relay_to_owner = false;
  225. }
  226. if ($parent['origin']) {
  227. $relay_to_owner = false;
  228. }
  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 (dbm::is_result($r)) {
  252. foreach ($r as $rr) {
  253. $recipients_followup[] = $rr['id'];
  254. }
  255. }
  256. }
  257. }
  258. logger("Notify ".$target_item["guid"]." via PuSH: ".($push_notify?"Yes":"No"), LOGGER_DEBUG);
  259. } else {
  260. $followup = false;
  261. logger('Distributing directly '.$target_item["guid"], LOGGER_DEBUG);
  262. // don't send deletions onward for other people's stuff
  263. if ($target_item['deleted'] && (! intval($target_item['wall']))) {
  264. logger('notifier: ignoring delete notification for non-wall item');
  265. return;
  266. }
  267. if ((strlen($parent['allow_cid']))
  268. || (strlen($parent['allow_gid']))
  269. || (strlen($parent['deny_cid']))
  270. || (strlen($parent['deny_gid']))) {
  271. $public_message = false; // private recipients, not public
  272. }
  273. $allow_people = expand_acl($parent['allow_cid']);
  274. $allow_groups = expand_groups(expand_acl($parent['allow_gid']),true);
  275. $deny_people = expand_acl($parent['deny_cid']);
  276. $deny_groups = expand_groups(expand_acl($parent['deny_gid']));
  277. // if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
  278. // a delivery fork. private groups (forum_mode == 2) do not uplink
  279. if ((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
  280. proc_run(PRIORITY_HIGH,'include/notifier.php','uplink',$item_id);
  281. }
  282. $conversants = array();
  283. foreach ($items as $item) {
  284. $recipients[] = $item['contact-id'];
  285. $conversants[] = $item['contact-id'];
  286. // pull out additional tagged people to notify (if public message)
  287. if ($public_message && strlen($item['inform'])) {
  288. $people = explode(',',$item['inform']);
  289. foreach ($people as $person) {
  290. if (substr($person,0,4) === 'cid:') {
  291. $recipients[] = intval(substr($person,4));
  292. $conversants[] = intval(substr($person,4));
  293. } else {
  294. $url_recipients[] = substr($person,4);
  295. }
  296. }
  297. }
  298. }
  299. if (count($url_recipients))
  300. logger('notifier: '.$target_item["guid"].' url_recipients ' . print_r($url_recipients,true));
  301. $conversants = array_unique($conversants);
  302. $recipients = array_unique(array_merge($recipients,$allow_people,$allow_groups));
  303. $deny = array_unique(array_merge($deny_people,$deny_groups));
  304. $recipients = array_diff($recipients,$deny);
  305. $conversant_str = dbesc(implode(', ',$conversants));
  306. }
  307. // If the thread parent is OStatus then do some magic to distribute the messages.
  308. // We have not only to look at the parent, since it could be a Friendica thread.
  309. if (($thr_parent AND ($thr_parent[0]['network'] == NETWORK_OSTATUS)) OR ($parent['network'] == NETWORK_OSTATUS)) {
  310. $diaspora_delivery = false;
  311. logger('Some parent is OStatus for '.$target_item["guid"]." - Author: ".$thr_parent[0]['author-link']." - Owner: ".$thr_parent[0]['owner-link'], LOGGER_DEBUG);
  312. // Send a salmon to the parent author
  313. $r = q("SELECT `url`, `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
  314. dbesc(normalise_link($thr_parent[0]['author-link'])),
  315. intval($uid));
  316. if (dbm::is_result($r)) {
  317. $probed_contact = $r[0];
  318. } else {
  319. $probed_contact = probe_url($thr_parent[0]['author-link']);
  320. }
  321. if ($probed_contact["notify"] != "") {
  322. logger('Notify parent author '.$probed_contact["url"].': '.$probed_contact["notify"]);
  323. $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
  324. }
  325. // Send a salmon to the parent owner
  326. $r = q("SELECT `url`, `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
  327. dbesc(normalise_link($thr_parent[0]['owner-link'])),
  328. intval($uid));
  329. if (dbm::is_result($r)) {
  330. $probed_contact = $r[0];
  331. } else {
  332. $probed_contact = probe_url($thr_parent[0]['owner-link']);
  333. }
  334. if ($probed_contact["notify"] != "") {
  335. logger('Notify parent owner '.$probed_contact["url"].': '.$probed_contact["notify"]);
  336. $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
  337. }
  338. // Send a salmon notification to every person we mentioned in the post
  339. $arr = explode(',',$target_item['tag']);
  340. foreach ($arr as $x) {
  341. //logger('Checking tag '.$x, LOGGER_DEBUG);
  342. $matches = null;
  343. if (preg_match('/@\[url=([^\]]*)\]/',$x,$matches)) {
  344. $probed_contact = probe_url($matches[1]);
  345. if ($probed_contact["notify"] != "") {
  346. logger('Notify mentioned user '.$probed_contact["url"].': '.$probed_contact["notify"]);
  347. $url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
  348. }
  349. }
  350. }
  351. // It only makes sense to distribute answers to OStatus messages to Friendica and OStatus - but not Diaspora
  352. $sql_extra = " AND `network` IN ('".NETWORK_OSTATUS."', '".NETWORK_DFRN."')";
  353. } else {
  354. $sql_extra = " AND `network` IN ('".NETWORK_OSTATUS."', '".NETWORK_DFRN."', '".NETWORK_DIASPORA."', '".NETWORK_MAIL."', '".NETWORK_MAIL2."')";
  355. }
  356. } else {
  357. $public_message = false;
  358. }
  359. // If this is a public message and pubmail is set on the parent, include all your email contacts
  360. $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
  361. if (! $mail_disabled) {
  362. if ((! strlen($target_item['allow_cid'])) && (! strlen($target_item['allow_gid']))
  363. && (! strlen($target_item['deny_cid'])) && (! strlen($target_item['deny_gid']))
  364. && (intval($target_item['pubmail']))) {
  365. $r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s'",
  366. intval($uid),
  367. dbesc(NETWORK_MAIL)
  368. );
  369. if (dbm::is_result($r)) {
  370. foreach ($r as $rr) {
  371. $recipients[] = $rr['id'];
  372. }
  373. }
  374. }
  375. }
  376. if ($followup) {
  377. $recip_str = implode(', ', $recipients_followup);
  378. } else {
  379. $recip_str = implode(', ', $recipients);
  380. }
  381. if ($relocate) {
  382. $r = $recipients_relocate;
  383. } else {
  384. $r = q("SELECT `id`, `url`, `network`, `self` FROM `contact`
  385. WHERE `id` IN (%s) AND NOT `blocked` AND NOT `pending` AND NOT `archive`".$sql_extra,
  386. dbesc($recip_str)
  387. );
  388. }
  389. // delivery loop
  390. if (dbm::is_result($r)) {
  391. foreach ($r as $contact) {
  392. if ($contact['self']) {
  393. continue;
  394. }
  395. logger("Deliver ".$target_item["guid"]." to ".$contact['url']." via network ".$contact['network'], LOGGER_DEBUG);
  396. proc_run(PRIORITY_HIGH,'include/delivery.php', $cmd, $item_id, $contact['id']);
  397. }
  398. }
  399. // send salmon slaps to mentioned remote tags (@foo@example.com) in OStatus posts
  400. // They are especially used for notifications to OStatus users that don't follow us.
  401. if ($slap && count($url_recipients) && ($public_message || $push_notify) && $normal_mode) {
  402. if (!get_config('system','dfrn_only')) {
  403. foreach ($url_recipients as $url) {
  404. if ($url) {
  405. logger('notifier: urldelivery: ' . $url);
  406. $deliver_status = slapper($owner,$url,$slap);
  407. /// @TODO Redeliver/queue these items on failure, though there is no contact record
  408. }
  409. }
  410. }
  411. }
  412. if ($public_message) {
  413. $r0 = array();
  414. $r1 = array();
  415. if ($diaspora_delivery) {
  416. if (!$followup) {
  417. $r0 = Diaspora::relay_list();
  418. }
  419. $r1 = q("SELECT `batch`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`name`) AS `name`, ANY_VALUE(`network`) AS `network`
  420. FROM `contact` WHERE `network` = '%s'
  421. AND `uid` = %d AND `rel` != %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` GROUP BY `batch` ORDER BY rand()",
  422. dbesc(NETWORK_DIASPORA),
  423. intval($owner['uid']),
  424. intval(CONTACT_IS_SHARING)
  425. );
  426. }
  427. $r2 = q("SELECT `id`, `name`,`network` FROM `contact`
  428. WHERE `network` in ( '%s', '%s') AND `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `archive`
  429. AND `rel` != %d order by rand() ",
  430. dbesc(NETWORK_DFRN),
  431. dbesc(NETWORK_MAIL2),
  432. intval($owner['uid']),
  433. intval(CONTACT_IS_SHARING)
  434. );
  435. $r = array_merge($r2,$r1,$r0);
  436. if (dbm::is_result($r)) {
  437. logger('pubdeliver '.$target_item["guid"].': '.print_r($r,true), LOGGER_DEBUG);
  438. foreach ($r as $rr) {
  439. // except for Diaspora batch jobs
  440. // Don't deliver to folks who have already been delivered to
  441. if (($rr['network'] !== NETWORK_DIASPORA) && (in_array($rr['id'],$conversants))) {
  442. logger('notifier: already delivered id=' . $rr['id']);
  443. continue;
  444. }
  445. if ((! $mail) && (! $fsuggest) && (! $followup)) {
  446. logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]);
  447. proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$rr['id']);
  448. }
  449. }
  450. }
  451. $push_notify = true;
  452. }
  453. // Notify PuSH subscribers (Used for OStatus distribution of regular posts)
  454. if ($push_notify AND strlen($hub)) {
  455. $hubs = explode(',', $hub);
  456. if (count($hubs)) {
  457. foreach ($hubs as $h) {
  458. $h = trim($h);
  459. if (! strlen($h)) {
  460. continue;
  461. }
  462. if ($h === '[internal]') {
  463. // Set push flag for PuSH subscribers to this topic,
  464. // they will be notified in queue.php
  465. q("UPDATE `push_subscriber` SET `push` = 1 ".
  466. "WHERE `nickname` = '%s' AND `push` = 0", dbesc($owner['nickname']));
  467. logger('Activating internal PuSH for item '.$item_id, LOGGER_DEBUG);
  468. } else {
  469. $params = 'hub.mode=publish&hub.url=' . urlencode( App::get_baseurl() . '/dfrn_poll/' . $owner['nickname'] );
  470. post_url($h,$params);
  471. logger('publish for item '.$item_id.' ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code());
  472. }
  473. if (count($hubs) > 1) {
  474. sleep(7); // try and avoid multiple hubs responding at precisely the same time
  475. }
  476. }
  477. }
  478. // Handling the pubsubhubbub requests
  479. proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
  480. }
  481. logger('notifier: calling hooks', LOGGER_DEBUG);
  482. if ($normal_mode) {
  483. call_hooks('notifier_normal',$target_item);
  484. }
  485. call_hooks('notifier_end',$target_item);
  486. return;
  487. }