]> git.mxchange.org Git - friendica.git/blob - include/notifier.php
bb38ecf515452f50ea8ce5359e65e273a7ea1cfc
[friendica.git] / include / notifier.php
1 <?php
2
3         require_once("boot.php");
4
5         $a = new App;
6
7         @include(".htconfig.php");
8         require_once("dba.php");
9         $db = new dba($db_host, $db_user, $db_pass, $db_data);
10                 unset($db_host, $db_user, $db_pass, $db_data);
11
12
13         require_once("session.php");
14         require_once("datetime.php");
15         require_once('include/items.php');
16         require_once('include/bbcode.php');
17
18         if($argc < 3)
19                 return;
20
21         $a->set_baseurl(get_config('system','url'));
22
23         logger('notifier: invoked: ' . print_r($argv,true));
24
25         $cmd = $argv[1];
26
27         switch($cmd) {
28
29                 case 'mail':
30                 default:
31                         $item_id = intval($argv[2]);
32                         if(! $item_id){
33                                 killme(); return;
34                         }
35                         break;
36         }
37
38         $recipients = array();
39         $url_recipients = array();
40
41         if($cmd === 'mail') {
42
43                 $message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
44                                 intval($item_id)
45                 );
46                 if(! count($message)){
47                         killme(); return;
48                 }
49                 $uid = $message[0]['uid'];
50                 $recipients[] = $message[0]['contact-id'];
51                 $item = $message[0];
52
53         }
54         else {
55                 // find ancestors
56
57                 $r = q("SELECT `parent`, `uid`, `edited` FROM `item` WHERE `id` = %d LIMIT 1",
58                         intval($item_id)
59                 );
60                 if(! count($r)){
61                         killme(); return;
62                 }
63
64                 $parent_id = $r[0]['parent'];
65                 $uid = $r[0]['uid'];
66                 $updated = $r[0]['edited'];
67
68                 $items = q("SELECT * FROM `item` WHERE `parent` = %d ORDER BY `id` ASC",
69                         intval($parent_id)
70                 );
71
72                 if(! count($items)){
73                         killme(); return;
74                 }
75         }
76
77         $r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, `user`.`page-flags` 
78                 FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` 
79                 WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
80                 intval($uid)
81         );
82
83         if(count($r))
84                 $owner = $r[0];
85         else {
86                 killme(); return;
87         }
88         $hub = get_config('system','huburl');
89
90         // If this is a public conversation, notify the feed hub
91         $notify_hub = true;
92
93         // fill this in with a single salmon slap if applicable
94         $slap = '';
95
96         if($cmd != 'mail') {
97
98                 require_once('include/group.php');
99
100                 $parent = $items[0];
101
102                 if($parent['type'] === 'remote') {
103                         // local followup to remote post
104                         $followup = true;
105                         $notify_hub = false; // not public
106                         $conversant_str = dbesc($parent['contact-id']);
107                 }
108                 else {
109                         $followup = false;
110
111                         if((strlen($parent['allow_cid'])) 
112                                 || (strlen($parent['allow_gid'])) 
113                                 || (strlen($parent['deny_cid'])) 
114                                 || (strlen($parent['deny_gid']))) {
115                                 $notify_hub = false; // private recipients, not public
116                         }
117
118                         $allow_people = expand_acl($parent['allow_cid']);
119                         $allow_groups = expand_groups(expand_acl($parent['allow_gid']));
120                         $deny_people = expand_acl($parent['deny_cid']);
121                         $deny_groups = expand_groups(expand_acl($parent['deny_gid']));
122
123                         $conversants = array();
124
125                         foreach($items as $item) {
126                                 $recipients[] = $item['contact-id'];
127                                 $conversants[] = $item['contact-id'];
128                                 // pull out additional tagged people to notify (if public message)
129                                 if($notify_hub && strlen($item['inform'])) {
130                                         $people = explode(',',$item['inform']);
131                                         foreach($people as $person) {
132                                                 if(substr($person,0,4) === 'cid:') {
133                                                         $recipients[] = intval(substr($person,4));
134                                                         $conversants[] = intval(substr($person,4));
135                                                 }
136                                                 else {
137                                                         $url_recipients[] = substr($person,4);
138                                                 }
139                                         }
140                                 }
141                         }
142
143                         logger('notifier: url_recipients' . print_r($url_recipients,true));
144
145                         $conversants = array_unique($conversants);
146
147
148                         $recipients = array_unique(array_merge($recipients,$allow_people,$allow_groups));
149                         $deny = array_unique(array_merge($deny_people,$deny_groups));
150                         $recipients = array_diff($recipients,$deny);
151
152                         $conversant_str = dbesc(implode(', ',$conversants));
153                 }
154
155                 $r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
156
157                 if( ! count($r)){
158                         killme(); return;
159                 }
160
161                 $contacts = $r;
162         }
163
164         $feed_template = load_view_file('view/atom_feed.tpl');
165         $mail_template = load_view_file('view/atom_mail.tpl');
166
167         $atom = '';
168         $hubxml = '';
169         $slaps = array();
170
171         if(strlen($hub)) {
172                 $hubs = explode(',', $hub);
173                 if(count($hubs)) {
174                         foreach($hubs as $h) {
175                                 $h = trim($h);
176                                 if(! strlen($h))
177                                         continue;
178                                 $hubxml .= '<link rel="hub" href="' . xmlify($h) . '" />' . "\n" ;
179                         }
180                 }
181         }
182
183         $atom .= replace_macros($feed_template, array(
184                         '$version'      => xmlify(FRIENDIKA_VERSION),
185                         '$feed_id'      => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
186                         '$feed_title'   => xmlify($owner['name']),
187                         '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
188                         '$hub'          => $hubxml,
189                         '$salmon'       => '',  // private feed, we don't use salmon here
190                         '$name'         => xmlify($owner['name']),
191                         '$profile_page' => xmlify($owner['url']),
192                         '$photo'        => xmlify($owner['photo']),
193                         '$thumb'        => xmlify($owner['thumb']),
194                         '$picdate'      => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
195                         '$uridate'      => xmlify(datetime_convert('UTC','UTC',$owner['uri-date']    . '+00:00' , ATOM_TIME)) ,
196                         '$namdate'      => xmlify(datetime_convert('UTC','UTC',$owner['name-date']   . '+00:00' , ATOM_TIME)) ,
197                         '$birthday'     => ''
198         ));
199
200         if($cmd === 'mail') {
201                 $notify_hub = false;  // mail is  not public
202
203                 $atom .= replace_macros($mail_template, array(
204                         '$name'         => xmlify($owner['name']),
205                         '$profile_page' => xmlify($owner['url']),
206                         '$thumb'        => xmlify($owner['thumb']),
207                         '$item_id'      => xmlify($item['uri']),
208                         '$subject'      => xmlify($item['title']),
209                         '$created'      => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00' , ATOM_TIME)),
210                         '$content'      => xmlify($item['body']),
211                         '$parent_id'    => xmlify($item['parent-uri'])
212                 ));
213         }
214         else {
215                 if($followup) {
216                         foreach($items as $item) {  // there is only one item
217                                 if($item['id'] == $item_id) {
218                                         logger('notifier: followup: item: ' . print_r($item,true), LOGGER_DATA);
219                                         $slap  = atom_entry($item,'html',$owner,$owner,false);
220                                         $atom .= atom_entry($item,'text',$owner,$owner,false);
221                                 }
222                         }
223                 }
224                 else {
225                         foreach($items as $item) {
226                                 $contact = get_item_contact($item,$contacts);
227                                 if(! $contact)
228                                         continue;
229
230                                 $atom   .= atom_entry($item,'text',$contact,$owner,true);
231
232                                 // There's a problem here - we *were* going to use salmon to provide semi-authenticated
233                                 // communication to OStatus, but unless we're the item author they won't verify.
234                                 // commented out for now, though we'll still send local replies (and any mentions 
235                                 // that they contain) upstream. Rethinking the problem space.
236  
237 //                              $slaps[] = atom_entry($item,'html',$contact,$owner,true);
238                         }
239                 }
240         }
241         $atom .= '</feed>' . "\r\n";
242
243         logger('notifier: ' . $atom, LOGGER_DATA);
244
245 //      logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA);
246
247         if($followup)
248                 $recip_str = $parent['contact-id'];
249         else
250                 $recip_str = implode(', ', $recipients);
251
252
253         $r = q("SELECT * FROM `contact` WHERE `id` IN ( %s ) AND `blocked` = 0 ",
254                 dbesc($recip_str)
255         );
256         if(! count($r)){
257                 killme(); return;
258         }
259         // delivery loop
260
261         require_once('include/salmon.php');
262
263         foreach($r as $contact) {
264                 if($contact['self'])
265                         continue;
266
267                 $deliver_status = 0;
268
269                 switch($contact['network']) {
270                         case 'dfrn':
271                                 logger('notifier: dfrndelivery: ' . $contact['name']);
272                                 $deliver_status = dfrn_deliver($owner,$contact,$atom);
273
274                                 logger('notifier: dfrn_delivery returns ' . $deliver_status);
275
276                                 if($deliver_status == (-1)) {
277                                         logger('notifier: delivery failed: queuing message');
278                                         // queue message for redelivery
279                                         q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
280                                                 VALUES ( %d, '%s', '%s', '%s') ",
281                                                 intval($contact['id']),
282                                                 dbesc(datetime_convert()),
283                                                 dbesc(datetime_convert()),
284                                                 dbesc($atom)
285                                         );
286                                 }
287                                 break;
288                         case 'stat':
289                                 if($followup && $contact['notify']) {
290                                         logger('notifier: slapdelivery: ' . $contact['name']);
291                                         $deliver_status = slapper($owner,$contact['notify'],$slap);
292
293                                         if($deliver_status == (-1)) {
294                                                 // queue message for redelivery
295                                                 q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
296                                                         VALUES ( %d, '%s', '%s', '%s') ",
297                                                         intval($contact['id']),
298                                                         dbesc(datetime_convert()),
299                                                         dbesc(datetime_convert()),
300                                                         dbesc($slap)
301                                                 );
302
303                                         }
304
305
306                                 }
307                                 else {
308
309                                         // only send salmon if public - e.g. if it's ok to notify
310                                         // a public hub, it's ok to send a salmon
311
312                                         if(count($slaps) && $notify_hub) {
313                                                 logger('notifier: slapdelivery: ' . $contact['name']);
314                                                 foreach($slaps as $slappy) {
315                                                         if($contact['notify']) {
316                                                                 $deliver_status = slapper($owner,$contact['notify'],$slappy);
317                                                                 if($deliver_status == (-1)) {
318                                                                         // queue message for redelivery
319                                                                         q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
320                                                                                 VALUES ( %d, '%s', '%s', '%s') ",
321                                                                                 intval($contact['id']),
322                                                                                 dbesc(datetime_convert()),
323                                                                                 dbesc(datetime_convert()),
324                                                                                 dbesc($slappy)
325                                                                         );                                                              
326                                                                 }
327                                                         }
328                                                 }
329                                         }
330                                 }
331                                 break;
332                         case 'mail':
333                         case 'dspr':
334                         case 'feed':
335                         default:
336                                 break;
337                 }
338         }
339                 
340         // send additional slaps to mentioned remote tags (@foo@example.com)
341
342         if($slap && count($url_recipients) && $followup && $notify_hub) {
343                 foreach($url_recipients as $url) {
344                         if($url) {
345                                 logger('notifier: urldelivery: ' . $url);
346                                 $deliver_status = slapper($owner,$url,$slap);
347                                 // TODO: redeliver/queue these items on failure, though there is no contact record
348                         }
349                 }
350         }
351
352         if((strlen($hub)) && ($notify_hub)) {
353                 $hubs = explode(',', $hub);
354                 if(count($hubs)) {
355                         foreach($hubs as $h) {
356                                 $h = trim($h);
357                                 if(! strlen($h))
358                                         continue;
359                                 $params = 'hub.mode=publish&hub.url=' . urlencode($a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] );
360                                 post_url($h,$params);
361                                 logger('pubsub: publish: ' . $h . ' returned ' . $a->get_curl_code());
362                                 if(count($hubs) > 1)
363                                         sleep(7);                               // try and avoid multiple hubs responding at precisely the same time
364                         }
365                 }
366         }
367
368         killme();
369