]> git.mxchange.org Git - friendica.git/blob - include/poller.php
Merge branch 'master', remote-tracking branch 'remotes/upstream/master'
[friendica.git] / include / poller.php
1 <?php
2
3 require_once("boot.php");
4
5
6 function poller_run($argv, $argc){
7         global $a, $db;
8
9         if(is_null($a)) {
10                 $a = new App;
11         }
12   
13         if(is_null($db)) {
14             @include(".htconfig.php");
15         require_once("dba.php");
16             $db = new dba($db_host, $db_user, $db_pass, $db_data);
17         unset($db_host, $db_user, $db_pass, $db_data);
18         };
19
20
21         require_once('include/session.php');
22         require_once('include/datetime.php');
23         require_once('library/simplepie/simplepie.inc');
24         require_once('include/items.php');
25         require_once('include/Contact.php');
26         require_once('include/email.php');
27         require_once('include/socgraph.php');
28
29         load_config('config');
30         load_config('system');
31
32         $a->set_baseurl(get_config('system','url'));
33
34         load_hooks();
35
36         logger('poller: start');
37         
38         // run queue delivery process in the background
39
40         proc_run('php',"include/queue.php");
41         
42         // expire any expired accounts
43
44         q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0 
45                 AND `account_expires_on` != '0000-00-00 00:00:00' 
46                 AND `account_expires_on` < UTC_TIMESTAMP() ");
47   
48         $abandon_days = intval(get_config('system','account_abandon_days'));
49         if($abandon_days < 1)
50                 $abandon_days = 0;
51
52         
53
54         // once daily run birthday_updates and then expire in background
55
56         $d1 = get_config('system','last_expire_day');
57         $d2 = intval(datetime_convert('UTC','UTC','now','d'));
58
59         if($d2 != intval($d1)) {
60
61                 update_contact_birthdays();
62
63                 update_suggestions();
64
65                 set_config('system','last_expire_day',$d2);
66                 proc_run('php','include/expire.php');
67         }
68
69         // clear old cache
70         Cache::clear();
71
72         // clear item cache files if they are older than one day
73         $cache = get_config('system','itemcache');
74         if (($cache != '') and is_dir($cache)) {
75                 if ($dh = opendir($cache)) {
76                         while (($file = readdir($dh)) !== false) {
77                                 $fullpath = $cache."/".$file;
78                                 if ((filetype($fullpath) == "file") and filectime($fullpath) < (time() - 86400))
79                                         unlink($fullpath);
80                         }
81                         closedir($dh);
82                 }
83         }
84
85         $manual_id  = 0;
86         $generation = 0;
87         $hub_update = false;
88         $force      = false;
89         $restart    = false;
90
91         if(($argc > 1) && ($argv[1] == 'force'))
92                 $force = true;
93
94         if(($argc > 1) && ($argv[1] == 'restart')) {
95                 $restart = true;
96                 $generation = intval($argv[2]);
97                 if(! $generation)
98                         killme();               
99         }
100
101         if(($argc > 1) && intval($argv[1])) {
102                 $manual_id = intval($argv[1]);
103                 $force     = true;
104         }
105
106         $sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
107
108         reload_plugins();
109
110         $d = datetime_convert();
111
112         if(! $restart)
113                 proc_run('php','include/cronhooks.php');
114
115         // Only poll from those with suitable relationships,
116         // and which have a polling address and ignore Diaspora since 
117         // we are unable to match those posts with a Diaspora GUID and prevent duplicates.
118
119         $abandon_sql = (($abandon_days) 
120                 ? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days)) 
121                 : '' 
122         );
123
124         $contacts = q("SELECT `contact`.`id` FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` 
125                 WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
126                 AND NOT `network` IN ( '%s', '%s' )
127                 $sql_extra 
128                 AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0 
129                 AND `user`.`account_expired` = 0 $abandon_sql ORDER BY RAND()",
130                 intval(CONTACT_IS_SHARING),
131                 intval(CONTACT_IS_FRIEND),
132                 dbesc(NETWORK_DIASPORA),
133                 dbesc(NETWORK_FACEBOOK)
134         );
135
136         if(! count($contacts)) {
137                 return;
138         }
139
140         foreach($contacts as $c) {
141
142                 $res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
143                         intval($c['id'])
144                 );
145
146                 if((! $res) || (! count($res)))
147                         continue;
148
149                 foreach($res as $contact) {
150
151                         $xml = false;
152
153                         if($manual_id)
154                                 $contact['last-update'] = '0000-00-00 00:00:00';
155
156                         if($contact['network'] === NETWORK_DFRN)
157                                 $contact['priority'] = 2;
158
159                         if(!get_config('system','ostatus_use_priority') and ($contact['network'] === NETWORK_OSTATUS))
160                                 $contact['priority'] = 2;
161
162                         if($contact['priority'] || $contact['subhub']) {
163
164                                 $hub_update = true;
165                                 $update     = false;
166
167                                 $t = $contact['last-update'];
168
169                                 // We should be getting everything via a hub. But just to be sure, let's check once a day.
170                                 // (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
171                                 // This also lets us update our subscription to the hub, and add or replace hubs in case it
172                                 // changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'. 
173
174
175                                 if($contact['subhub']) {
176                                         $interval = get_config('system','pushpoll_frequency');
177                                         $contact['priority'] = (($interval !== false) ? intval($interval) : 3);
178                                         $hub_update = false;
179         
180                                         if((datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) || $force)
181                                                         $hub_update = true;
182                                 }
183                                 else
184                                         $hub_update = false;
185
186                                 /**
187                                  * Based on $contact['priority'], should we poll this site now? Or later?
188                                  */                     
189
190                                 switch ($contact['priority']) {
191                                         case 5:
192                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
193                                                         $update = true;
194                                                 break;                                  
195                                         case 4:
196                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
197                                                         $update = true;
198                                                 break;
199                                         case 3:
200                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
201                                                         $update = true;
202                                                 break;
203                                         case 2:
204                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour"))
205                                                         $update = true;
206                                                 break;
207                                         case 1:
208                                         default:
209                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour"))
210                                                         $update = true;
211                                                 break;
212                                 }
213                                 if((! $update) && (! $force))
214                                         continue;
215                         }
216
217                         // Check to see if we are running out of memory - if so spawn a new process and kill this one
218
219                         $avail_memory = return_bytes(ini_get('memory_limit'));
220                         $memused = memory_get_peak_usage(true);
221                         if(intval($avail_memory)) {
222                                 if(($memused / $avail_memory) > 0.95) {
223                                         if($generation + 1 > 10) {
224                                                 logger('poller: maximum number of spawns exceeded. Terminating.');
225                                                 killme();
226                                         }
227                                         logger('poller: memory exceeded. ' . $memused . ' bytes used. Spawning new poll.');
228                                         proc_run('php', 'include/poller.php', 'restart', (string) $generation + 1);
229                                         killme();
230                                 }
231                         }
232
233                         $importer_uid = $contact['uid'];
234                 
235                         $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` LEFT JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
236                                 intval($importer_uid)
237                         );
238                         if(! count($r))
239                                 continue;
240
241                         $importer = $r[0];
242
243                         logger("poller: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
244
245                         $last_update = (($contact['last-update'] === '0000-00-00 00:00:00') 
246                                 ? datetime_convert('UTC','UTC','now - 30 days', ATOM_TIME)
247                                 : datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
248                         );
249
250                         if($contact['network'] === NETWORK_DFRN) {
251
252                                 $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
253
254                                 if(intval($contact['duplex']) && $contact['dfrn-id'])
255                                         $idtosend = '0:' . $orig_id;
256                                 if(intval($contact['duplex']) && $contact['issued-id'])
257                                         $idtosend = '1:' . $orig_id;
258
259                                 // they have permission to write to us. We already filtered this in the contact query.
260                                 $perm = 'rw';
261
262                                 $url = $contact['poll'] . '?dfrn_id=' . $idtosend 
263                                         . '&dfrn_version=' . DFRN_PROTOCOL_VERSION 
264                                         . '&type=data&last_update=' . $last_update 
265                                         . '&perm=' . $perm ;
266         
267                                 $handshake_xml = fetch_url($url);
268
269                                 logger('poller: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA);
270
271
272                                 if(! $handshake_xml) {
273                                         logger("poller: $url appears to be dead - marking for death ");
274                                         // dead connection - might be a transient event, or this might
275                                         // mean the software was uninstalled or the domain expired. 
276                                         // Will keep trying for one month.
277                                         mark_for_death($contact);
278
279                                         // set the last-update so we don't keep polling
280
281                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
282                                                 dbesc(datetime_convert()),
283                                                 intval($contact['id'])
284                                         );
285
286                                         continue;
287                                 }
288
289                                 if(! strstr($handshake_xml,'<?xml')) {
290                                         logger('poller: response from ' . $url . ' did not contain XML.');
291                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
292                                                 dbesc(datetime_convert()),
293                                                 intval($contact['id'])
294                                         );
295                                         continue;
296                                 }
297
298
299                                 $res = parse_xml_string($handshake_xml);
300         
301                                 if(intval($res->status) == 1) {
302                                         logger("poller: $url replied status 1 - marking for death ");
303
304                                         // we may not be friends anymore. Will keep trying for one month.
305                                         // set the last-update so we don't keep polling
306
307                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
308                                                 dbesc(datetime_convert()),
309                                                 intval($contact['id'])
310                                         );
311
312                                         mark_for_death($contact);
313                                 }
314                                 else {
315                                         if($contact['term-date'] != '0000-00-00 00:00:00') {
316                                                 logger("poller: $url back from the dead - removing mark for death");
317                                                 unmark_for_death($contact);
318                                         }
319                                 }
320
321                                 if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
322                                         continue;
323
324                                 if(((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) {
325                                         q("update contact set poco = '%s' where id = %d limit 1",
326                                                 dbesc(str_replace('/profile/','/poco/', $contact['url'])),
327                                                 intval($contact['id'])
328                                         );
329                                 }
330
331                                 $postvars = array();
332
333                                 $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
334                                 $challenge    = hex2bin((string) $res->challenge);
335
336                                 $final_dfrn_id = '';
337
338                                 if(($contact['duplex']) && strlen($contact['prvkey'])) {
339                                         openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
340                                         openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
341                                 }
342                                 else {
343                                         openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
344                                         openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
345                                 }
346
347                                 $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
348
349                                 if(strpos($final_dfrn_id,':') == 1)
350                                         $final_dfrn_id = substr($final_dfrn_id,2);
351
352                                 if($final_dfrn_id != $orig_id) {
353                                         logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);    
354                                         // did not decode properly - cannot trust this site 
355                                         continue;
356                                 }
357
358                                 $postvars['dfrn_id'] = $idtosend;
359                                 $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
360                                 $postvars['perm'] = 'rw';
361
362                                 $xml = post_url($contact['poll'],$postvars);
363                         }
364                         elseif(($contact['network'] === NETWORK_OSTATUS) 
365                                 || ($contact['network'] === NETWORK_DIASPORA)
366                                 || ($contact['network'] === NETWORK_FEED) ) {
367
368                                 // Upgrading DB fields from an older Friendica version
369                                 // Will only do this once per notify-enabled OStatus contact
370                                 // or if relationship changes
371
372                                 $stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0);
373
374                                 if($stat_writeable != $contact['writable']) {
375                                         q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
376                                                 intval($stat_writeable),
377                                                 intval($contact['id'])
378                                         );
379                                 }
380
381                                 // Are we allowed to import from this person?
382
383                                 if($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly'])
384                                         continue;
385
386                                 $xml = fetch_url($contact['poll']);
387                         }
388                         elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
389
390                                 logger("Mail: Fetching");
391
392                                 $mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
393                                 if($mail_disabled)
394                                         continue;
395
396                                 logger("Mail: Enabled");
397
398                                 $mbox = null;
399                                 $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
400                                         intval($importer_uid)
401                                 );
402                                 $mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1",
403                                         intval($importer_uid)
404                                 );
405                                 if(count($x) && count($mailconf)) {
406                                     $mailbox = construct_mailbox_name($mailconf[0]);
407                                         $password = '';
408                                         openssl_private_decrypt(hex2bin($mailconf[0]['pass']),$password,$x[0]['prvkey']);
409                                         $mbox = email_connect($mailbox,$mailconf[0]['user'],$password);
410                                         unset($password);
411                                         logger("Mail: Connect");
412                                         if($mbox) {
413                                                 q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
414                                                         dbesc(datetime_convert()),
415                                                         intval($mailconf[0]['id']),
416                                                         intval($importer_uid)
417                                                 );
418                                         }
419                                 }
420                                 if($mbox) {
421                                         logger("Mail: mbox");
422
423                                         $msgs = email_poll($mbox,$contact['addr']);
424
425                                         if(count($msgs)) {
426                                                 logger("Mail: Parsing ".count($msgs)." mails.");
427
428                                                 foreach($msgs as $msg_uid) {
429                                                         logger("Mail: Parsing mail ".$msg_uid);
430
431                                                         $datarray = array();
432                                                         $meta = email_msg_meta($mbox,$msg_uid);
433                                                         $headers = email_msg_headers($mbox,$msg_uid);
434
435                                                         // look for a 'references' header and try and match with a parent item we have locally.
436
437                                                         $raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : '');
438                                                         $datarray['uri'] = msgid2iri(trim($meta->message_id,'<>'));
439
440                                                         if($raw_refs) {
441                                                                 $refs_arr = explode(' ', $raw_refs);
442                                                                 if(count($refs_arr)) {
443                                                                         for($x = 0; $x < count($refs_arr); $x ++)
444                                                                                 $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
445                                                                 }
446                                                                 $qstr = implode(',',$refs_arr);
447                                                                 $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
448                                                                         intval($importer_uid)
449                                                                 );
450                                                                 if(count($r))
451                                                                         $datarray['parent-uri'] = $r[0]['uri'];
452                                                         }
453
454
455                                                         if(! x($datarray,'parent-uri'))
456                                                                 $datarray['parent-uri'] = $datarray['uri'];
457
458                                                         // Have we seen it before?
459                                                         $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1",
460                                                                 intval($importer_uid),
461                                                                 dbesc($datarray['uri'])
462                                                         );
463
464                                                         if(count($r)) {
465                                                                 logger("Mail: Seen before ".$msg_uid);
466                                                                 if($meta->deleted && ! $r[0]['deleted']) {
467                                                                         q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1",
468                                                                                 dbesc(datetime_convert()),
469                                                                                 intval($r[0]['id'])
470                                                                         );
471                                                                 }
472                                                                 switch ($mailconf[0]['action']) {
473                                                                         case 0:
474                                                                                 break;
475                                                                         case 1:
476                                                                                 logger("Mail: Deleting ".$msg_uid);
477                                                                                 imap_delete($mbox, $msg_uid, FT_UID);
478                                                                                 break;
479                                                                         case 2:
480                                                                                 logger("Mail: Mark as seen ".$msg_uid);
481                                                                                 imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
482                                                                                 break;
483                                                                         case 3:
484                                                                                 logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
485                                                                                 imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
486                                                                                 if ($mailconf[0]['movetofolder'] != "")
487                                                                                         imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
488                                                                                 break;
489                                                                 }
490                                                                 continue;
491                                                         }
492
493                                                         // Decoding the header
494                                                         $subject = imap_mime_header_decode($meta->subject);
495                                                         $datarray['title'] = "";
496                                                         foreach($subject as $subpart)
497                                                                 if ($subpart->charset != "default")
498                                                                         $datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text);
499                                                                 else
500                                                                         $datarray['title'] .= $subpart->text;
501
502                                                         $datarray['title'] = notags(trim($datarray['title']));
503
504                                                         //$datarray['title'] = notags(trim($meta->subject));
505                                                         $datarray['created'] = datetime_convert('UTC','UTC',$meta->date);
506
507                                                         $r = email_get_msg($mbox,$msg_uid);
508                                                         if(! $r) {
509                                                                 logger("Mail: can't fetch msg ".$msg_uid);
510                                                                 continue;
511                                                         }
512                                                         $datarray['body'] = escape_tags($r['body']);
513
514                                                         logger("Mail: Importing ".$msg_uid);
515
516                                                         // some mailing lists have the original author as 'from' - add this sender info to msg body.
517                                                         // todo: adding a gravatar for the original author would be cool
518
519                                                         if(! stristr($meta->from,$contact['addr'])) {
520                                                                 $from = imap_mime_header_decode($meta->from);
521                                                                 $fromdecoded = "";
522                                                                 foreach($from as $frompart)
523                                                                         if ($frompart->charset != "default")
524                                                                                 $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
525                                                                         else
526                                                                                 $fromdecoded .= $frompart->text;
527
528                                                                 $datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body'];
529                                                         }
530
531                                                         $datarray['uid'] = $importer_uid;
532                                                         $datarray['contact-id'] = $contact['id'];
533                                                         if($datarray['parent-uri'] === $datarray['uri'])
534                                                                 $datarray['private'] = 1;
535                                                         if(($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) {
536                                                                 $datarray['private'] = 1;
537                                                                 $datarray['allow_cid'] = '<' . $contact['id'] . '>';
538                                                         }
539                                                         $datarray['author-name'] = $contact['name'];
540                                                         $datarray['author-link'] = 'mailbox';
541                                                         $datarray['author-avatar'] = $contact['photo'];
542
543                                                         $stored_item = item_store($datarray);
544                                                         q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d",
545                                                                 dbesc($datarray['parent-uri']),
546                                                                 intval($importer_uid)
547                                                         );
548                                                         q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
549                                                                 intval($stored_item)
550                                                         );
551                                                         switch ($mailconf[0]['action']) {
552                                                                 case 0:
553                                                                         break;
554                                                                 case 1:
555                                                                         logger("Mail: Deleting ".$msg_uid);
556                                                                         imap_delete($mbox, $msg_uid, FT_UID);
557                                                                         break;
558                                                                 case 2:
559                                                                         logger("Mail: Mark as seen ".$msg_uid);
560                                                                         imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
561                                                                         break;
562                                                                 case 3:
563                                                                         logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
564                                                                         imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
565                                                                         if ($mailconf[0]['movetofolder'] != "")
566                                                                                 imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
567                                                                         break;
568                                                         }
569                                                 }
570                                         }
571
572                                         imap_close($mbox);
573                                 }
574                         }
575                         elseif($contact['network'] === NETWORK_FACEBOOK) {
576                                 // This is picked up by the Facebook plugin on a cron hook.
577                                 // Ignored here.
578                         }
579
580                         if($xml) {
581                                 logger('poller: received xml : ' . $xml, LOGGER_DATA);
582
583                                 if(! strstr($xml,'<?xml')) {
584                                         logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
585                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
586                                                 dbesc(datetime_convert()),
587                                                 intval($contact['id'])
588                                         );
589                                         continue;
590                                 }
591
592
593                                 consume_feed($xml,$importer,$contact,$hub,1,1);
594
595                                 // do it twice. Ensures that children of parents which may be later in the stream aren't tossed
596         
597                                 consume_feed($xml,$importer,$contact,$hub,1,2);
598
599                                 $hubmode = 'subscribe';
600                                 if($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly'])
601                                         $hubmode = 'unsubscribe';
602
603                                 if((strlen($hub)) && ($hub_update) && ($contact['rel'] != CONTACT_IS_FOLLOWER)) {
604                                         logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
605                                         $hubs = explode(',', $hub);
606                                         if(count($hubs)) {
607                                                 foreach($hubs as $h) {
608                                                         $h = trim($h);
609                                                         if(! strlen($h))
610                                                                 continue;
611                                                         subscribe_to_hub($h,$importer,$contact,$hubmode);
612                                                 }
613                                         }
614                                 }
615                         }
616
617
618                         $updated = datetime_convert();
619
620                         $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d LIMIT 1",
621                                 dbesc($updated),
622                                 dbesc($updated),
623                                 intval($contact['id'])
624                         );
625
626
627                         // load current friends if possible.
628
629                         if($contact['poco']) {  
630                                 $r = q("SELECT count(*) as total from glink 
631                                         where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
632                                         intval($contact['id'])
633                                 );
634                         }
635                         if(count($r)) {
636                                 if(! $r[0]['total']) {
637                                         poco_load($contact['id'],$importer_uid,$contact['poco']);
638                                 }
639                         }
640
641                         // loop - next contact
642                 }
643         }
644
645                 
646         return;
647 }
648
649 if (array_search(__file__,get_included_files())===0){
650   poller_run($argv,$argc);
651   killme();
652 }