]> git.mxchange.org Git - friendica.git/blobdiff - include/items.php
Merge pull request #279 from fermionic/generate-random-id-bug-in-statusnet-api
[friendica.git] / include / items.php
old mode 100755 (executable)
new mode 100644 (file)
index 1a7aa6c..a1dcdb6
@@ -7,14 +7,11 @@ require_once('include/crypto.php');
 
 function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) {
 
-       // default permissions - anonymous user
-
-       if(! strlen($owner_nick))
-               killme();
 
+       $sitefeed    = ((strlen($owner_nick)) ? false : true); // not yet implemented, need to rewrite huge chunks of following logic
        $public_feed = (($dfrn_id) ? false : true);
-       $starred = false;
-       $converse = false;
+       $starred     = false;   // not yet implemented, possible security issues
+       $converse    = false;
 
        if($public_feed && $a->argc > 2) {
                for($x = 2; $x < $a->argc; $x++) {
@@ -22,13 +19,20 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
                                $converse = true;
                        if($a->argv[$x] == 'starred')
                                $starred = true;
+                       if($a->argv[$x] === 'category' && $a->argc > ($x + 1) && strlen($a->argv[$x+1]))
+                               $category = $a->argv[$x+1];
                }
+
+
        }
 
+       
+
+       // default permissions - anonymous user
 
        $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid`  = '' AND `deny_gid`  = '' ";
 
-       $r = q("SELECT `contact`.*, `user`.`uid` AS `user_uid`, `user`.`nickname`, `user`.`timezone`
+       $r = q("SELECT `contact`.*, `user`.`uid` AS `user_uid`, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`
                FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
                WHERE `contact`.`self` = 1 AND `user`.`nickname` = '%s' LIMIT 1",
                dbesc($owner_nick)
@@ -103,6 +107,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
        if(! strlen($last_update))
                $last_update = 'now -30 days';
 
+       if(isset($category)) {
+               $sql_extra .= file_tag_file_query('item',$category,'category');
+       }
+
        if($public_feed) {
                if(! $converse)
                        $sql_extra .= " AND `contact`.`self` = 1 ";
@@ -156,7 +164,8 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
                '$picdate'      => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
                '$uridate'      => xmlify(datetime_convert('UTC','UTC',$owner['uri-date']    . '+00:00' , ATOM_TIME)) ,
                '$namdate'      => xmlify(datetime_convert('UTC','UTC',$owner['name-date']   . '+00:00' , ATOM_TIME)) , 
-               '$birthday'     => ((strlen($birthday)) ? '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>' : '')
+               '$birthday'     => ((strlen($birthday)) ? '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>' : ''),
+               '$community'    => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
        ));
 
        call_hooks('atom_feed', $atom);
@@ -417,7 +426,7 @@ function get_atom_elements($feed,$item) {
        // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining 
        // html.
 
-       if((strpos($res['body'],'<') !== false) || (strpos($res['body'],'>') !== false)) {
+       if((strpos($res['body'],'<') !== false) && (strpos($res['body'],'>') !== false)) {
 
                $res['body'] = reltoabs($res['body'],$base_url);
 
@@ -430,14 +439,22 @@ function get_atom_elements($feed,$item) {
 
                // we shouldn't need a whitelist, because the bbcode converter
                // will strip out any unsupported tags.
-               // $config->set('HTML.Allowed', 'p,b,a[href],i'); 
 
                $purifier = new HTMLPurifier($config);
                $res['body'] = $purifier->purify($res['body']);
 
-               $res['body'] = html2bbcode($res['body']);
+               $res['body'] = @html2bbcode($res['body']);
+       }
+       elseif(! $have_real_body) {
+
+               // it's not one of our messages and it has no tags
+               // so it's probably just text. We'll escape it just to be safe.
+
+               $res['body'] = escape_tags($res['body']);
        }
 
+       // this tag is obsolete but we keep it for really old sites
+
        $allow = $item->get_item_tags(NAMESPACE_DFRN,'comment-allow');
        if($allow && $allow[0]['data'] == 1)
                $res['last-child'] = 1;
@@ -571,20 +588,21 @@ function get_atom_elements($feed,$item) {
 
        if($rawobj) {
                $res['object'] = '<object>' . "\n";
-               if($rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
-                       $res['object-type'] = $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'];
-                       $res['object'] .= '<type>' . $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
+               $child = $rawobj[0]['child'];
+               if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
+                       $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'];
+                       $res['object'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
                }       
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
-                       $res['object'] .= '<id>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
-                       $res['object'] .= '<link>' . encode_rel_links($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n";
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
-                       $res['object'] .= '<title>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n";
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
-                       $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
+                       $res['object'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
+                       $res['object'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n";
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
+                       $res['object'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n";
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
+                       $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
                        if(! $body)
-                               $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
+                               $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
                        // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
                        $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n";
                        if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
@@ -609,20 +627,20 @@ function get_atom_elements($feed,$item) {
 
        if($rawobj) {
                $res['target'] = '<target>' . "\n";
-               if($rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
-                       $res['target'] .= '<type>' . $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
+               $child = $rawobj[0]['child'];
+               if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
+                       $res['target'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
                }       
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
-                       $res['target'] .= '<id>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
-
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
-                       $res['target'] .= '<link>' . encode_rel_links($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n";
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
-                       $res['target'] .= '<title>' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n";
-               if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
-                       $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
+                       $res['target'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
+                       $res['target'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n";
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
+                       $res['target'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n";
+               if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
+                       $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
                        if(! $body)
-                               $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
+                               $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
                        // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
                        $res['target'] .= '<orig>' . xmlify($body) . '</orig>' . "\n";
                        if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
@@ -682,7 +700,7 @@ function item_store($arr,$force_parent = false) {
                unset($arr['dsprsig']);
        }
 
-       if($arr['gravity'])
+       if(x($arr, 'gravity'))
                $arr['gravity'] = intval($arr['gravity']);
        elseif($arr['parent-uri'] === $arr['uri'])
                $arr['gravity'] = 0;
@@ -742,6 +760,7 @@ function item_store($arr,$force_parent = false) {
 
        if($arr['parent-uri'] === $arr['uri']) {
                $parent_id = 0;
+               $parent_deleted = 0;
                $allow_cid = $arr['allow_cid'];
                $allow_gid = $arr['allow_gid'];
                $deny_cid  = $arr['deny_cid'];
@@ -800,6 +819,8 @@ function item_store($arr,$force_parent = false) {
                                logger('item_store: item parent was not found - ignoring item');
                                return 0;
                        }
+                       
+                       $parent_deleted = 0;
                }
        }
 
@@ -1043,6 +1064,22 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
        if(! $rino_enable)
                $rino = 0;
 
+       $ssl_val = intval(get_config('system','ssl_policy'));
+       $ssl_policy = '';
+
+       switch($ssl_val){
+               case SSL_POLICY_FULL:
+                       $ssl_policy = 'full';
+                       break;
+               case SSL_POLICY_SELFSIGN:
+                       $ssl_policy = 'self';
+                       break;                  
+               case SSL_POLICY_NONE:
+               default:
+                       $ssl_policy = 'none';
+                       break;
+       }
+
        $url = $contact['notify'] . '&dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . (($rino) ? '&rino=1' : '');
 
        logger('dfrn_deliver: ' . $url);
@@ -1072,11 +1109,23 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
        $postvars     = array();
        $sent_dfrn_id = hex2bin((string) $res->dfrn_id);
        $challenge    = hex2bin((string) $res->challenge);
+       $perm         = (($res->perm) ? $res->perm : null);
        $dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0);
        $rino_allowed = ((intval($res->rino) === 1) ? 1 : 0);
+       $page         = (($owner['page-flags'] == PAGE_COMMUNITY) ? 1 : 0);
 
        $final_dfrn_id = '';
 
+       if($perm) {
+               if((($perm == 'rw') && (! intval($contact['writable']))) 
+               || (($perm == 'r') && (intval($contact['writable'])))) {
+                       q("update contact set writable = %d where id = %d limit 1",
+                               intval(($perm == 'rw') ? 1 : 0),
+                               intval($contact['id'])
+                       );
+                       $contact['writable'] = (string) 1 - intval($contact['writable']);                       
+               }
+       }
 
        if(($contact['duplex'] && strlen($contact['pubkey'])) 
                || ($owner['page-flags'] == PAGE_COMMUNITY && strlen($contact['pubkey']))
@@ -1115,6 +1164,11 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
                $postvars['perm'] = 'r';
        }
 
+       $postvars['ssl_policy'] = $ssl_policy;
+
+       if($page)
+               $postvars['page'] = '1';
+       
        if($rino && $rino_allowed && (! $dissolve)) {
                $key = substr(random_string(),0,16);
                $data = bin2hex(aes_encrypt($postvars['data'],$key));
@@ -1379,6 +1433,19 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
 
        }
 
+       $community_page = 0;
+       $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'community');
+       if($rawtags) {
+               $community_page = intval($rawtags[0]['data']);
+       }
+       if(is_array($contact) && intval($contact['forum']) != $community_page) {
+               q("update contact set forum = %d where id = %d limit 1",
+                       intval($community_page),
+                       intval($contact['id'])
+               );
+               $contact['forum'] = (string) $community_page;
+       }
+
 
        // process any deleted entries
 
@@ -1398,7 +1465,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                        }
                        if($deleted && is_array($contact)) {
                                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join `contact` on `item`.`contact-id` = `contact`.`id` 
-                                       WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d LIMIT 1",
+                                       WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
                                        dbesc($uri),
                                        intval($importer['uid']),
                                        intval($contact['id'])
@@ -1409,7 +1476,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                                        if(! $item['deleted'])
                                                logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
 
-                                       if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTVITY_OBJ_TAGTERM)) {
+                                       if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
                                                $xo = parse_xml_string($item['object'],false);
                                                $xt = parse_xml_string($item['target'],false);
                                                if($xt->type === ACTIVITY_OBJ_NOTE) {
@@ -1543,9 +1610,10 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
 
                                if(count($r)) {
                                        if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) {  
-                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
                                                        dbesc($datarray['title']),
                                                        dbesc($datarray['body']),
+                                                       dbesc($datarray['tag']),
                                                        dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
                                                        dbesc($item_id),
                                                        intval($importer['uid'])
@@ -1688,9 +1756,10 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
 
                                if(count($r)) {
                                        if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) {  
-                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
                                                        dbesc($datarray['title']),
                                                        dbesc($datarray['body']),
+                                                       dbesc($datarray['tag']),
                                                        dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
                                                        dbesc($item_id),
                                                        intval($importer['uid'])
@@ -1761,7 +1830,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                                        // but otherwise there's a possible data mixup on the sender's system.
                                        // the tgroup delivery code called from item_store will correct it if it's a forum,
                                        // but we're going to unconditionally correct it here so that the post will always be owned by our contact. 
-                                       logger('local_delivery: Correcting item owner.', LOGGER_DEBUG);
+                                       logger('consume_feed: Correcting item owner.', LOGGER_DEBUG);
                                        $datarray['owner-name']   = $contact['name'];
                                        $datarray['owner-link']   = $contact['url'];
                                        $datarray['owner-avatar'] = $contact['thumb'];
@@ -1798,6 +1867,8 @@ function local_delivery($importer,$data) {
        $feed->enable_order_by_date(false);
        $feed->init();
 
+/*
+       // Currently unsupported - needs a lot of work
        $reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' );
        if(isset($reloc[0]['child'][NAMESPACE_DFRN])) {
                $base = $reloc[0]['child'][NAMESPACE_DFRN];
@@ -1822,6 +1893,7 @@ function local_delivery($importer,$data) {
                // schedule a scan?
 
        }
+*/
 
        // handle friend suggestion notification
 
@@ -1857,6 +1929,14 @@ function local_delivery($importer,$data) {
                );
                if(count($r)) {
                        $fid = $r[0]['id'];
+
+                       // OK, we do. Do we already have an introduction for this person ?
+                       $r = q("select id from intro where uid = %d and fid = %d limit 1",
+                               intval($fsugg['uid']),
+                               intval($fid)
+                       );
+                       if(count($r))
+                               return 0;
                }
                if(! $fid)
                        $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ",
@@ -1877,6 +1957,7 @@ function local_delivery($importer,$data) {
                else
                        return 0;
 
+
                $hash = random_string();
  
                $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )
@@ -1962,6 +2043,19 @@ function local_delivery($importer,$data) {
 
                // NOTREACHED
        }       
+
+       $community_page = 0;
+       $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'community');
+       if($rawtags) {
+               $community_page = intval($rawtags[0]['data']);
+       }
+       if(intval($importer['forum']) != $community_page) {
+               q("update contact set forum = %d where id = %d limit 1",
+                       intval($community_page),
+                       intval($importer['id'])
+               );
+               $importer['forum'] = (string) $community_page;
+       }
        
        logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
 
@@ -1984,7 +2078,7 @@ function local_delivery($importer,$data) {
                        if($deleted) {
 
                                $r = q("SELECT `item`.*, `contact`.`self` FROM `item` left join contact on `item`.`contact-id` = `contact`.`id`
-                                       WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d LIMIT 1",
+                                       WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
                                        dbesc($uri),
                                        intval($importer['importer_uid']),
                                        intval($importer['id'])
@@ -1998,9 +2092,10 @@ function local_delivery($importer,$data) {
 
                                        logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
 
-                                       if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTVITY_OBJ_TAGTERM)) {
+                                       if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
                                                $xo = parse_xml_string($item['object'],false);
                                                $xt = parse_xml_string($item['target'],false);
+
                                                if($xt->type === ACTIVITY_OBJ_NOTE) {
                                                        $i = q("select * from `item` where uri = '%s' and uid = %d limit 1",
                                                                dbesc($xt->id),
@@ -2132,8 +2227,36 @@ function local_delivery($importer,$data) {
                                logger('local_delivery: received remote comment');
                                $is_like = false;
                                // remote reply to our post. Import and then notify everybody else.
+
                                $datarray = get_atom_elements($feed,$item);
 
+                               $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body`  FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+                                       dbesc($item_id),
+                                       intval($importer['importer_uid'])
+                               );
+
+                               // Update content if 'updated' changes
+
+                               if(count($r)) {
+                                       $iid = $r[0]['id'];
+                                       if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) {  
+                                               logger('received updated comment' , LOGGER_DEBUG);
+                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+                                                       dbesc($datarray['title']),
+                                                       dbesc($datarray['body']),
+                                                       dbesc($datarray['tag']),
+                                                       dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
+                                                       dbesc($item_id),
+                                                       intval($importer['importer_uid'])
+                                               );
+
+                                               proc_run('php',"include/notifier.php","comment-import",$iid);
+
+                                       }
+
+                                       continue;
+                               }
+
 
                                // TODO: make this next part work against both delivery threads of a community post
 
@@ -2143,14 +2266,22 @@ function local_delivery($importer,$data) {
 //                                     return 0;
 //                             }                                       
 
+                               // our user with $importer['importer_uid'] is the owner
+
+                               $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1",
+                                       intval($importer['importer_uid'])
+                               );
+
+
                                $datarray['type'] = 'remote-comment';
                                $datarray['wall'] = 1;
                                $datarray['parent-uri'] = $parent_uri;
                                $datarray['uid'] = $importer['importer_uid'];
-                               $datarray['owner-name'] = $r[0]['name'];
-                               $datarray['owner-link'] = $r[0]['url'];
-                               $datarray['owner-avatar'] = $r[0]['thumb'];
+                               $datarray['owner-name'] = $own[0]['name'];
+                               $datarray['owner-link'] = $own[0]['url'];
+                               $datarray['owner-avatar'] = $own[0]['thumb'];
                                $datarray['contact-id'] = $importer['id'];
+
                                if(($datarray['verb'] === ACTIVITY_LIKE) || ($datarray['verb'] === ACTIVITY_DISLIKE)) {
                                        $is_like = true;
                                        $datarray['type'] = 'activity';
@@ -2167,26 +2298,34 @@ function local_delivery($importer,$data) {
                                }
 
                                if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
-
-
+                                       
                                        $xo = parse_xml_string($datarray['object'],false);
                                        $xt = parse_xml_string($datarray['target'],false);
 
-                                       if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id == $r[0]['uri'])) {
+                                       if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id)) {
+
+                                               // fetch the parent item
+
+                                               $tagp = q("select * from item where uri = '%s' and uid = %d limit 1",
+                                                       dbesc($xt->id),
+                                                       intval($importer['importer_uid'])
+                                               );
+                                               if(! count($tagp))
+                                                       continue;       
 
                                                // extract tag, if not duplicate, and this user allows tags, add to parent item                                         
 
                                                if($xo->id && $xo->content) {
                                                        $newtag = '#[url=' . $xo->id . ']'. $xo->content . '[/url]';
-
-                                                       if(! (stristr($r[0]['tag'],$newtag))) {
+                                                       if(! (stristr($tagp[0]['tag'],$newtag))) {
                                                                $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1",
                                                                        intval($importer['importer_uid'])
                                                                );
-                                                               if(count($i) && ! ($i[0]['blocktags'])) {
-                                                                       q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1",
-                                                                               dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag),
-                                                                               intval($r[0]['id'])
+                                                               if(count($i) && ! intval($i[0]['blocktags'])) {
+                                                                       q("UPDATE item SET tag = '%s', `edited` = '%s' WHERE id = %d LIMIT 1",
+                                                                               dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag),
+                                                                               intval($tagp[0]['id']),
+                                                                               dbesc(datetime_convert())
                                                                        );
                                                                }
                                                        }
@@ -2279,9 +2418,10 @@ function local_delivery($importer,$data) {
 
                                if(count($r)) {
                                        if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) {  
-                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+                                               $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
                                                        dbesc($datarray['title']),
                                                        dbesc($datarray['body']),
+                                                       dbesc($datarray['tag']),
                                                        dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
                                                        dbesc($item_id),
                                                        intval($importer['importer_uid'])
@@ -2353,9 +2493,9 @@ function local_delivery($importer,$data) {
 
                                // find out if our user is involved in this conversation and wants to be notified.
                        
-                               if($datarray['type'] != 'activity') {
+                               if(!x($datarray['type']) || $datarray['type'] != 'activity') {
 
-                                       $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
+                                       $myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0",
                                                dbesc($parent_uri),
                                                intval($importer['importer_uid'])
                                        );
@@ -2444,9 +2584,10 @@ function local_delivery($importer,$data) {
 
                        if(count($r)) {
                                if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) {  
-                                       $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+                                       $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
                                                dbesc($datarray['title']),
                                                dbesc($datarray['body']),
+                                               dbesc($datarray['tag']),
                                                dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
                                                dbesc($item_id),
                                                intval($importer['importer_uid'])
@@ -2872,6 +3013,11 @@ function item_expire($uid,$days) {
 
        foreach($r as $item) {
 
+               // don't expire filed items
+
+               if(strpos($item['file'],'[') !== false)
+                       continue;
+
                // Only expire posts, not photos and photo comments
 
                if($expire_photos==0 && strlen($item['resource-id']))
@@ -2883,12 +3029,23 @@ function item_expire($uid,$days) {
                if($expire_items==0 && $item['type']!='note')
                        continue;
 
+
                $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1",
                        dbesc(datetime_convert()),
                        dbesc(datetime_convert()),
                        intval($item['id'])
                );
 
+               $r = q("DELETE FROM item_id where iid in (select id from item where parent = %d) and uid = %d",
+                       intval($item['id']),
+                       intval($uid)
+               );
+
+               $r = q("DELETE FROM sign where iid in (select id from item where parent = %d) and uid = %d",
+                       intval($item['id']),
+                       intval($uid)
+               );
+
                // kill the kids
 
                $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
@@ -2908,7 +3065,7 @@ function item_expire($uid,$days) {
 function drop_items($items) {
        $uid = 0;
 
-       if((! local_user()) && (! $remote_user()))
+       if(! local_user() && ! remote_user())
                return;
 
        if(count($items)) {