]> git.mxchange.org Git - friendica.git/blob - include/poller.php
friend finder support functions
[friendica.git] / include / poller.php
1 <?php
2 require_once("boot.php");
3
4 function poller_run($argv, $argc){
5         global $a, $db;
6
7         if(is_null($a)) {
8                 $a = new App;
9         }
10   
11         if(is_null($db)) {
12             @include(".htconfig.php");
13         require_once("dba.php");
14             $db = new dba($db_host, $db_user, $db_pass, $db_data);
15         unset($db_host, $db_user, $db_pass, $db_data);
16         };
17
18         require_once('session.php');
19         require_once('datetime.php');
20         require_once('simplepie/simplepie.inc');
21         require_once('include/items.php');
22         require_once('include/Contact.php');
23
24         $a->set_baseurl(get_config('system','url'));
25
26         logger('poller: start');
27         
28         // run queue delivery process in the background
29
30         proc_run('php',"include/queue.php");
31         
32         // clear old cache
33         q("DELETE FROM `cache` WHERE `updated` < '%s'",
34                 dbesc(datetime_convert('UTC','UTC',"now - 30 days")));
35
36         $manual_id  = 0;
37         $hub_update = false;
38         $force      = false;
39
40         if(($argc > 1) && ($argv[1] == 'force'))
41                 $force = true;
42
43         if(($argc > 1) && intval($argv[1])) {
44                 $manual_id = intval($argv[1]);
45                 $force     = true;
46         }
47
48         $sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
49
50         $d = datetime_convert();
51         call_hooks('cron', $d);
52
53         reload_plugins();
54
55         $contacts = q("SELECT `id` FROM `contact` 
56                 WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
57                 $sql_extra 
58                 AND `self` = 0 AND `blocked` = 0 AND `readonly` = 0 ORDER BY RAND()",
59                 intval(REL_FAN),
60                 intval(REL_BUD)
61         );
62
63         if(! count($contacts)) {
64                 return;
65         }
66
67         foreach($contacts as $c) {
68
69                 $res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
70                         intval($c['id'])
71                 );
72
73                 if(! count($res))
74                         continue;
75
76                 foreach($res as $contact) {
77                         if($manual_id)
78                                 $contact['last-update'] = '0000-00-00 00:00:00';
79
80                         if($contact['priority'] || $contact['subhub']) {
81
82                                 $hub_update = true;
83                                 $update     = false;
84
85                                 $t = $contact['last-update'];
86
87                                 // We should be getting everything via a hub. But just to be sure, let's check once a day.
88                                 // (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
89                                 // This also lets us update our subscription to the hub, and add or replace hubs in case it
90                                 // changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'. 
91
92
93                                 if($contact['subhub']) {
94                                         $interval = get_config('system','pushpoll_frequency');
95                                         $contact['priority'] = (($interval !== false) ? intval($interval) : 3);
96                                         $hub_update = false;
97         
98                                         if((datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) || $force)
99                                                         $hub_update = true;
100                                 }
101
102                                 /**
103                                  * Based on $contact['priority'], should we poll this site now? Or later?
104                                  */                     
105
106                                 switch ($contact['priority']) {
107                                         case 5:
108                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
109                                                         $update = true;
110                                                 break;                                  
111                                         case 4:
112                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
113                                                         $update = true;
114                                                 break;
115                                         case 3:
116                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
117                                                         $update = true;
118                                                 break;
119                                         case 2:
120                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour"))
121                                                         $update = true;
122                                                 break;
123                                         case 1:
124                                         default:
125                                                 if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour"))
126                                                         $update = true;
127                                                 break;
128                                 }
129                                 if((! $update) && (! $force))
130                                         continue;
131                         }
132
133                         $importer_uid = $contact['uid'];
134                 
135                         $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1",
136                                 intval($importer_uid)
137                         );
138                         if(! count($r))
139                                 continue;
140
141                         $importer = $r[0];
142
143                         logger("poller: poll: IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
144
145                         $last_update = (($contact['last-update'] === '0000-00-00 00:00:00') 
146                                 ? datetime_convert('UTC','UTC','now - 30 days', ATOM_TIME)
147                                 : datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
148                         );
149
150                         if($contact['network'] === 'dfrn') {
151
152                                 $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
153
154                                 if(intval($contact['duplex']) && $contact['dfrn-id'])
155                                         $idtosend = '0:' . $orig_id;
156                                 if(intval($contact['duplex']) && $contact['issued-id'])
157                                         $idtosend = '1:' . $orig_id;            
158
159                                 $url = $contact['poll'] . '?dfrn_id=' . $idtosend 
160                                         . '&dfrn_version=' . DFRN_PROTOCOL_VERSION 
161                                         . '&type=data&last_update=' . $last_update ;
162         
163                                 $xml = fetch_url($url);
164
165                                 logger('poller: handshake with url ' . $url . ' returns xml: ' . $xml, LOGGER_DATA);
166
167
168                                 if(! $xml) {
169                                         logger("poller: $url appears to be dead - marking for death ");
170                                         // dead connection - might be a transient event, or this might
171                                         // mean the software was uninstalled or the domain expired. 
172                                         // Will keep trying for one month.
173                                         mark_for_death($contact);
174
175                                         // set the last-update so we don't keep polling
176
177                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
178                                                 dbesc(datetime_convert()),
179                                                 intval($contact['id'])
180                                         );
181
182                                         continue;
183                                 }
184
185                                 if(! strstr($xml,'<?xml')) {
186                                         logger('poller: response from ' . $url . ' did not contain XML.');
187                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
188                                                 dbesc(datetime_convert()),
189                                                 intval($contact['id'])
190                                         );
191                                         continue;
192                                 }
193
194
195                                 $res = simplexml_load_string($xml);
196         
197                                 if(intval($res->status) == 1) {
198                                         logger("poller: $url replied status 1 - marking for death ");
199
200                                         // we may not be friends anymore. Will keep trying for one month.
201                                         // set the last-update so we don't keep polling
202
203                                         $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
204                                                 dbesc(datetime_convert()),
205                                                 intval($contact['id'])
206                                         );
207
208                                         mark_for_death($contact);
209                                 }
210                                 else {
211                                         if($contact['term-date'] != '0000-00-00 00:00:00') {
212                                                 logger("poller: $url back from the dead - removing mark for death");
213                                                 unmark_for_death($contact);
214                                         }
215                                 }
216
217                                 if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
218                                         continue;
219
220                                 $postvars = array();
221
222                                 $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
223                                 $challenge    = hex2bin((string) $res->challenge);
224
225                                 $final_dfrn_id = '';
226
227                                 if(($contact['duplex']) && strlen($contact['prvkey'])) {
228                                         openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
229                                         openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
230                                 }
231                                 else {
232                                         openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
233                                         openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
234                                 }
235
236                                 $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
237
238                                 if(strpos($final_dfrn_id,':') == 1)
239                                         $final_dfrn_id = substr($final_dfrn_id,2);
240
241                                 if($final_dfrn_id != $orig_id) {
242         
243                                         // did not decode properly - cannot trust this site 
244                                         continue;
245                                 }
246
247                                 $postvars['dfrn_id'] = $idtosend;
248                                 $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
249
250                                 $xml = post_url($contact['poll'],$postvars);
251                         }
252                         else {
253
254                                 // $contact['network'] !== 'dfrn'
255
256                                 $xml = fetch_url($contact['poll']);
257                         }
258
259                         logger('poller: received xml : ' . $xml, LOGGER_DATA);
260
261                         if(! strstr($xml,'<?xml')) {
262                                 logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
263                                 $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
264                                         dbesc(datetime_convert()),
265                                         intval($contact['id'])
266                                 );
267                                 continue;
268                         }
269
270                         consume_feed($xml,$importer,$contact,$hub,1);
271
272                         // do it twice. Ensures that children of parents which may be later in the stream aren't tossed
273
274                         consume_feed($xml,$importer,$contact,$hub,1);
275
276
277                         if((strlen($hub)) && ($hub_update) 
278                                 && (($contact['rel'] == REL_BUD) || (($contact['network'] === 'stat') && (! $contact['readonly'])))) {
279                                 logger('poller: subscribing to hub(s) : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
280                                 $hubs = explode(',', $hub);
281                                 if(count($hubs)) {
282                                         foreach($hubs as $h) {
283                                                 $h = trim($h);
284                                                 if(! strlen($h))
285                                                         continue;
286                                                 subscribe_to_hub($h,$importer,$contact);
287                                         }
288                                 }
289                         }
290
291
292                         $updated = datetime_convert();
293
294                         $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d LIMIT 1",
295                                 dbesc($updated),
296                                 dbesc($updated),
297                                 intval($contact['id'])
298                         );
299
300                         // loop - next contact
301                 }
302         }
303                 
304         return;
305 }
306
307 if (array_search(__file__,get_included_files())===0){
308   poller_run($argv,$argc);
309   killme();
310 }