3 require_once('bbcode.php');
5 function get_feed_for(&$a, $dfrn_id, $owner_id, $last_update, $direction = 0) {
8 // default permissions - anonymous user
17 if(strlen($owner_id) && ! intval($owner_id)) {
18 $r = q("SELECT `uid`, `nickname` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
22 $owner_id = $r[0]['uid'];
23 $owner_nick = $r[0]['nickname'];
27 $r = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
35 if($dfrn_id && $dfrn_id != '*') {
40 $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
44 $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
45 $my_id = '1:' . $dfrn_id;
48 $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
49 $my_id = '0:' . $dfrn_id;
56 $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `contact`.`uid` = %d $sql_extra LIMIT 1",
64 $groups = init_groups_visitor($contact['id']);
67 for($x = 0; $x < count($groups); $x ++)
68 $groups[$x] = '<' . intval($groups[$x]) . '>' ;
69 $gs = implode('|', $groups);
72 $gs = '<<>>' ; // Impossible to match
74 $sql_extra = sprintf("
75 AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' )
76 AND ( `deny_cid` = '' OR NOT `deny_cid` REGEXP '<%d>' )
77 AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )
78 AND ( `deny_gid` = '' OR NOT `deny_gid` REGEXP '%s')
80 intval($contact['id']),
81 intval($contact['id']),
87 if($dfrn_id === '' || $dfrn_id === '*')
92 if(! strlen($last_update))
93 $last_update = 'now - 30 days';
95 $check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
97 $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
98 `contact`.`name`, `contact`.`photo`, `contact`.`url`,
99 `contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
100 `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
101 `contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`
102 FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
103 WHERE `item`.`uid` = %d AND `item`.`visible` = 1
104 AND `item`.`wall` = 1 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
105 AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )
107 ORDER BY `parent` %s, `created` ASC LIMIT 0, 300",
114 // Will check further below if this actually returned results.
115 // We will provide an empty feed in any case.
119 $feed_template = load_view_file('view/atom_feed.tpl');
120 $tomb_template = load_view_file('view/atom_tomb.tpl');
121 $item_template = load_view_file('view/atom_item.tpl');
122 $cmnt_template = load_view_file('view/atom_cmnt.tpl');
126 $hub = get_config('system','huburl');
128 $hubxml = ((strlen($hub)) ? '<link rel="hub" href="' . xmlify($hub) . '" />' . "\n" : '');
131 $atom .= replace_macros($feed_template, array(
132 '$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner_nick),
133 '$feed_title' => xmlify($owner['name']),
134 '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
136 '$name' => xmlify($owner['name']),
137 '$profile_page' => xmlify($owner['url']),
138 '$photo' => xmlify($owner['photo']),
139 '$thumb' => xmlify($owner['thumb']),
140 '$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
141 '$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
142 '$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME))
146 if(! count($items)) {
147 $atom .= '</feed>' . "\r\n";
151 foreach($items as $item) {
153 // public feeds get html, our own nodes use bbcode
155 if($dfrn_id === '*') {
156 $item['body'] = bbcode($item['body']);
163 if($item['deleted']) {
164 $atom .= replace_macros($tomb_template, array(
165 '$id' => xmlify($item['uri']),
166 '$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00' , ATOM_TIME))
170 $verb = construct_verb($item);
171 $actobj = construct_activity($item);
173 if($item['parent'] == $item['id']) {
174 $atom .= replace_macros($item_template, array(
175 '$name' => xmlify($item['name']),
176 '$profile_page' => xmlify($item['url']),
177 '$thumb' => xmlify($item['thumb']),
178 '$owner_name' => xmlify($item['owner-name']),
179 '$owner_profile_page' => xmlify($item['owner-link']),
180 '$owner_thumb' => xmlify($item['owner-avatar']),
181 '$item_id' => xmlify($item['uri']),
182 '$title' => xmlify($item['title']),
183 '$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00' , ATOM_TIME)),
184 '$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00' , ATOM_TIME)),
185 '$location' => xmlify($item['location']),
187 '$alt' => xmlify($a->get_baseurl() . '/display/' . $owner_nick . '/' . $item['id']),
188 '$content' => xmlify($item['body']),
189 '$verb' => xmlify($verb),
190 '$actobj' => $actobj, // do not xmlify
191 '$comment_allow' => ((($item['last-child']) && ($contact['rel']) && ($contact['rel'] != REL_FAN)) ? 1 : 0)
195 $atom .= replace_macros($cmnt_template, array(
196 '$name' => xmlify($item['name']),
197 '$profile_page' => xmlify($item['url']),
198 '$thumb' => xmlify($item['thumb']),
199 '$item_id' => xmlify($item['uri']),
200 '$title' => xmlify($item['title']),
201 '$published' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00' , ATOM_TIME)),
202 '$updated' => xmlify(datetime_convert('UTC', 'UTC', $item['edited'] . '+00:00' , ATOM_TIME)),
204 '$content' => xmlify($item['body']),
205 '$alt' => xmlify($a->get_baseurl() . '/display/' . $owner_nick . '/' . $item['id']),
206 '$verb' => xmlify($verb),
207 '$actobj' => $actobj, // do not xmlify
208 '$parent_id' => xmlify($item['parent-uri']),
209 '$comment_allow' => (($item['last-child']) ? 1 : 0)
215 $atom .= '</feed>' . "\r\n";
220 function construct_verb($item) {
222 return $item['verb'];
223 return ACTIVITY_POST;
226 function construct_activity($item) {
228 if($item['object']) {
229 $o = '<as:object>' . "\r\n";
230 $r = @simplexml_load_string($item['object']);
232 $o .= '<as:object-type>' . $r->type . '</as:object-type>' . "\r\n";
234 $o .= '<id>' . $r->id . '</id>' . "\r\n";
236 $o .= '<link rel="alternate" type="text/html" href="' . $r->link . '" />' . "\r\n";
238 $o .= '<title>' . $r->title . '</title>' . "\r\n";
240 $o .= '<content type="html" >' . bbcode($r->content) . '</content>' . "\r\n";
241 $o .= '</as:object>' . "\r\n";
251 function get_atom_elements($item) {
253 require_once('library/HTMLPurifier.auto.php');
254 require_once('include/html2bbcode.php');
258 $raw_author = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author');
260 if($raw_author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['rel'] === 'photo')
261 $res['author-avatar'] = unxmlify($raw_author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['href']);
264 $author = $item->get_author();
265 $res['author-name'] = unxmlify($author->get_name());
266 $res['author-link'] = unxmlify($author->get_link());
267 if(! $res['author-avatar'])
268 $res['author-avatar'] = unxmlify($author->get_avatar());
269 $res['uri'] = unxmlify($item->get_id());
270 $res['title'] = unxmlify($item->get_title());
271 $res['body'] = unxmlify($item->get_content());
273 $maxlen = get_max_import_size();
274 if($maxlen && (strlen($res['body']) > $maxlen))
275 $res['body'] = substr($res['body'],0, $maxlen);
277 // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust
278 // the content type. Our own network only emits text normally, though it might have been converted to
279 // html if we used a pubsubhubbub transport. But if we see even one html open tag in our text, we will
280 // have to assume it is all html and needs to be purified.
282 // It doesn't matter all that much security wise - because before this content is used anywhere, we are
283 // going to escape any tags we find regardless, but this lets us import a limited subset of html from
284 // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining
288 if(strpos($res['body'],'<')) {
290 $res['body'] = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s',
291 '[youtube]$1[/youtube]', $res['body']);
293 $config = HTMLPurifier_Config::createDefault();
294 $config->set('Core.DefinitionCache', null);
296 // we shouldn't need a whitelist, because the bbcode converter
297 // will strip out any unsupported tags.
298 // $config->set('HTML.Allowed', 'p,b,a[href],i');
300 $purifier = new HTMLPurifier($config);
301 $res['body'] = $purifier->purify($res['body']);
305 $res['body'] = html2bbcode($res['body']);
308 $allow = $item->get_item_tags(NAMESPACE_DFRN,'comment-allow');
309 if($allow && $allow[0]['data'] == 1)
310 $res['last-child'] = 1;
312 $res['last-child'] = 0;
314 $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published');
316 $res['created'] = unxmlify($rawcreated[0]['data']);
318 $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location');
320 $res['location'] = unxmlify($rawlocation[0]['data']);
323 $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'updated');
325 $res['edited'] = unxmlify($rawcreated[0]['data']);
327 $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
328 if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
329 $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']);
330 elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data'])
331 $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']);
332 if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])
333 $res['owner-link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']);
334 elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])
335 $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']);
337 if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['rel'] === 'photo')
338 $res['owner-avatar'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['href']);
339 elseif($rawowner[0]['child'][NAMESPACE_DFRN]['avatar'][0]['data'])
340 $res['owner-avatar'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']);
342 $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
343 // select between supported verbs
345 $res['verb'] = unxmlify($rawverb[0]['data']);
347 $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object');
351 $res['object'] = '<object>' . "\n";
352 if($rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
353 $res['object-type'] = $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'];
354 $res['object'] .= '<type>' . $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
356 if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
357 $res['object'] .= '<id>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
359 if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['rel'] === 'alternate')
360 $res['object'] .= '<link>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'][0]['attribs']['']['href'] . '</link>' . "\n";
361 if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
362 $res['object'] .= '<title>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n";
363 if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
364 $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
366 $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
367 if(strpos($body,'<')) {
369 $body = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s',
370 '[youtube]$1[/youtube]', $body);
372 $config = HTMLPurifier_Config::createDefault();
373 $config->set('Core.DefinitionCache', null);
375 $purifier = new HTMLPurifier($config);
376 $body = $purifier->purify($body);
379 $body = html2bbcode($body);
380 $res['object'] .= '<content>' . $body . '</content>' . "\n";
383 $res['object'] .= '</object>' . "\n";
389 function item_store($arr) {
395 $arr['gravity'] = intval($arr['gravity']);
396 elseif($arr['parent-uri'] == $arr['uri'])
398 elseif($arr['verb'] == ACTIVITY_POST)
402 $arr['type'] = 'remote';
403 $arr['wall'] = ((intval($arr['wall'])) ? 1 : 0);
404 $arr['uri'] = notags(trim($arr['uri']));
405 $arr['author-name'] = notags(trim($arr['author-name']));
406 $arr['author-link'] = notags(trim($arr['author-link']));
407 $arr['author-avatar'] = notags(trim($arr['author-avatar']));
408 $arr['owner-name'] = notags(trim($arr['owner-name']));
409 $arr['owner-link'] = notags(trim($arr['owner-link']));
410 $arr['owner-avatar'] = notags(trim($arr['owner-avatar']));
411 $arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert());
412 $arr['edited'] = ((x($arr,'edited') !== false) ? datetime_convert('UTC','UTC',$arr['edited']) : datetime_convert());
413 $arr['changed'] = datetime_convert();
414 $arr['title'] = notags(trim($arr['title']));
415 $arr['location'] = notags(trim($arr['location']));
416 $arr['body'] = escape_tags(trim($arr['body']));
417 $arr['last-child'] = intval($arr['last-child']);
418 $arr['visible'] = ((x($arr,'visible') !== false) ? intval($arr['visible']) : 1);
420 $arr['parent-uri'] = notags(trim($arr['parent-uri']));
421 $arr['verb'] = notags(trim($arr['verb']));
422 $arr['object-type'] = notags(trim($arr['object-type']));
423 $arr['object'] = trim($arr['object']);
426 $parent_missing = false;
430 $r = q("INSERT INTO `item` (`"
431 . implode("`, `", array_keys($arr))
433 . implode("', '", array_values($arr))
436 // find the parent and snarf the item id and ACL's
438 $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
439 dbesc($arr['parent-uri']),
444 $parent_id = $r[0]['id'];
445 $allow_cid = $r[0]['allow_cid'];
446 $allow_gid = $r[0]['allow_gid'];
447 $deny_cid = $r[0]['deny_cid'];
448 $deny_gid = $r[0]['deny_gid'];
451 $parent_missing = true;
454 $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
455 $arr['uri'], // already dbesc'd
459 $current_post = $r[0]['id'];
463 if($parent_missing) {
465 // perhaps the parent was deleted, but in any case, this thread is dead
466 // and unfortunately our brand new item now has to be destroyed
468 q("DELETE FROM `item` WHERE `id` = %d LIMIT 1",
469 intval($current_post)
474 // Set parent id - all of the parent's ACL's are also inherited by this post
476 $r = q("UPDATE `item` SET `parent` = %d, `allow_cid` = '%s', `allow_gid` = '%s',
477 `deny_cid` = '%s', `deny_gid` = '%s' WHERE `id` = %d LIMIT 1",
483 intval($current_post)
486 return $current_post;
489 function get_item_contact($item,$contacts) {
490 if(! count($contacts) || (! is_array($item)))
492 foreach($contacts as $contact) {
493 if($contact['id'] == $item['contact-id']) {
502 function dfrn_deliver($contact,$atom,$debugging = false) {
505 if((! strlen($contact['dfrn-id'])) && (! $contact['duplex']))
508 $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
510 if($contact['duplex'] && $contact['dfrn-id'])
511 $idtosend = '0:' . $orig_id;
512 if($contact['duplex'] && $contact['issued-id'])
513 $idtosend = '1:' . $orig_id;
515 $url = $contact['notify'] . '?dfrn_id=' . $idtosend;
520 $xml = fetch_url($url);
528 $res = simplexml_load_string($xml);
530 if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
531 return (($res->status) ? $res->status : 3);
534 $sent_dfrn_id = hex2bin($res->dfrn_id);
535 $challenge = hex2bin($res->challenge);
539 if($contact['duplex'] && strlen($contact['prvkey'])) {
540 openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
541 openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
544 openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
545 openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
548 $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
550 if(strpos($final_dfrn_id,':') == 1)
551 $final_dfrn_id = substr($final_dfrn_id,2);
553 if($final_dfrn_id != $orig_id) {
554 // did not decode properly - cannot trust this site
558 $postvars['dfrn_id'] = $idtosend;
561 if(($contact['rel']) && ($contact['rel'] != REL_FAN) && (! $contact['blocked']) && (! $contact['readonly'])) {
562 $postvars['data'] = $atom;
565 $postvars['data'] = str_replace('<dfrn:comment-allow>1','<dfrn:comment-allow>0',$atom);
568 $xml = post_url($contact['notify'],$postvars);
573 $res = simplexml_load_string($xml);
580 function consume_feed($xml,$importer,$contact) {
582 require_once('simplepie/simplepie.inc');
584 $feed = new SimplePie();
585 $feed->set_raw_data($xml);
586 $feed->enable_order_by_date(false);
589 // Check at the feed level for updated contact name and/or photo
593 $photo_timestamp = '';
596 $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
598 $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
599 if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
600 $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
601 $new_name = $elems['name'][0]['data'];
603 if(($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
604 $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
605 $photo_url = $elems['link'][0]['attribs']['']['href'];
608 if(! $photo_timestamp) {
609 $photo_rawupdate = $feed->get_feed_tags(NAMESPACE_DFRN,'icon-updated');
610 if($photo_rawupdate) {
611 $photo_timestamp = datetime_convert('UTC','UTC',$photo_rawupdate[0]['data']);
612 $photo_url = $feed->get_image_url();
615 if(($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $contact['avatar-date'])) {
617 require_once("Photo.php");
618 $photo_failure = false;
620 $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1",
621 intval($contact['id']),
622 intval($contact['uid'])
625 $resource_id = $r[0]['resource-id'];
626 $img_str = fetch_url($photo_url,true);
627 $img = new Photo($img_str);
629 q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND contact-id` = %d AND `uid` = %d",
631 intval($contact['id']),
632 intval($contact['uid'])
635 $img->scaleImageSquare(175);
637 $hash = $resource_id;
638 $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), t('Contact Photos') , 4);
640 $img->scaleImage(80);
641 $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), t('Contact Photos') , 5);
643 q("UPDATE `contact` SET `avatar-date` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1",
644 dbesc(datetime_convert()),
645 intval($contact['uid']),
646 intval($contact['id'])
652 if(($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) {
653 q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d LIMIT 1",
654 dbesc(notags(trim($new_name))),
655 dbesc(datetime_convert()),
656 intval($contact['uid']),
657 intval($contact['id'])
661 // Now process the feed
662 if($feed->get_item_quantity()) {
663 foreach($feed->get_items() as $item) {
667 $rawdelete = $item->get_item_tags( NAMESPACE_TOMB, 'deleted-entry');
668 if(isset($rawdelete[0]['attribs']['']['ref'])) {
669 $uri = $rawthread[0]['attribs']['']['ref'];
671 if(isset($rawdelete[0]['attribs']['']['when'])) {
672 $when = $rawthread[0]['attribs']['']['when'];
673 $when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s');
676 $when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
679 $r = q("SELECT * FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
681 intval($importer['uid'])
685 if($item['uri'] == $item['parent-uri']) {
686 $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
687 `body` = '', `title` = ''
688 WHERE `parent-uri` = '%s' AND `uid` = %d",
690 dbesc(datetime_convert()),
692 intval($importer['uid'])
696 $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
697 `body` = '', `title` = ''
698 WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
700 dbesc(datetime_convert()),
702 intval($importer['uid'])
704 if($item['last-child']) {
705 // ensure that last-child is set in case the comment that had it just got wiped.
706 $q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
707 dbesc(datetime_convert()),
708 dbesc($item['parent-uri']),
711 // who is the last child now?
712 $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d
713 ORDER BY `edited` DESC LIMIT 1",
714 dbesc($item['parent-uri']),
715 intval($importer['uid'])
718 q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
730 $item_id = $item->get_id();
731 $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to');
732 if(isset($rawthread[0]['attribs']['']['ref'])) {
734 $parent_uri = $rawthread[0]['attribs']['']['ref'];
740 // Have we seen it? If not, import it.
742 $item_id = $item->get_id();
744 $r = q("SELECT `uid`, `last-child`, `edited` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
746 intval($importer['uid'])
748 // FIXME update content if 'updated' changes
750 $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
751 if($allow && $allow[0]['data'] != $r[0]['last-child']) {
752 $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
753 dbesc(datetime_convert()),
755 intval($importer['uid'])
757 $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
758 intval($allow[0]['data']),
759 dbesc(datetime_convert()),
761 intval($importer['uid'])
767 $datarray = get_atom_elements($item);
768 $datarray['parent-uri'] = $parent_uri;
769 $datarray['uid'] = $importer['uid'];
770 $datarray['contact-id'] = $contact['id'];
771 if(($datarray['verb'] == ACTIVITY_LIKE) || ($datarray['verb'] == ACTIVITY_DISLIKE)) {
772 $datarray['type'] = 'activity';
773 $datarray['gravity'] = GRAVITY_LIKE;
776 $r = item_store($datarray);
781 // Head post of a conversation. Have we seen it? If not, import it.
783 $item_id = $item->get_id();
784 $r = q("SELECT `uid`, `last-child`, `edited` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
786 intval($importer['uid'])
789 $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
790 if($allow && $allow[0]['data'] != $r[0]['last-child']) {
791 $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
792 intval($allow[0]['data']),
793 dbesc(datetime_convert()),
795 intval($importer['uid'])
800 $datarray = get_atom_elements($item);
801 $datarray['parent-uri'] = $item_id;
802 $datarray['uid'] = $importer['uid'];
803 $datarray['contact-id'] = $contact['id'];
804 $r = item_store($datarray);