]> git.mxchange.org Git - friendica.git/blobdiff - include/items.php
vier: fix missing icons
[friendica.git] / include / items.php
index eaa0565467d2459facee812f082151fbc3b907be..eff13668992a6c47a03ae9a021ae643b23c3a326 100644 (file)
@@ -13,6 +13,7 @@ require_once('include/threads.php');
 require_once('include/socgraph.php');
 require_once('include/plaintext.php');
 require_once('include/ostatus.php');
+require_once('include/feed.php');
 require_once('mod/share.php');
 
 require_once('library/defuse/php-encryption-1.2.1/Crypto.php');
@@ -969,7 +970,7 @@ function query_page_info($url, $no_photos = false, $photo = "", $keywords = fals
        $data = Cache::get("parse_url:".$url);
        if (is_null($data)){
                $data = parseurl_getsiteinfo($url, true);
-               Cache::set("parse_url:".$url,serialize($data));
+               Cache::set("parse_url:".$url,serialize($data), CACHE_DAY);
        } else
                $data = unserialize($data);
 
@@ -1096,6 +1097,48 @@ function add_guid($item) {
                dbesc($item["uri"]), dbesc($item["network"]));
 }
 
+// Adds a "lang" specification in a "postopts" element of given $arr,
+// if possible and not already present.
+// Expects "body" element to exist in $arr.
+// TODO: add a parameter to request forcing override
+function item_add_language_opt(&$arr) {
+
+       if (version_compare(PHP_VERSION, '5.3.0', '<')) return; // LanguageDetect.php not available ?
+
+       if ( x($arr, 'postopts') )
+       {
+               if ( strstr($arr['postopts'], 'lang=') )
+               {
+                       // do not override
+                       // TODO: add parameter to request overriding
+                       return;
+               }
+               $postopts = $arr['postopts'];
+       }
+       else
+       {
+               $postopts = "";
+       }
+
+       require_once('library/langdet/Text/LanguageDetect.php');
+       $naked_body = preg_replace('/\[(.+?)\]/','',$arr['body']);
+       $l = new Text_LanguageDetect;
+       //$lng = $l->detectConfidence($naked_body);
+       //$arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
+       $lng = $l->detect($naked_body, 3);
+
+       if (sizeof($lng) > 0) {
+               if ($postopts != "") $postopts .= '&'; // arbitrary separator, to be reviewed
+               $postopts .= 'lang=';
+               $sep = "";
+               foreach ($lng as $language => $score) {
+                       $postopts .= $sep . $language.";".$score;
+                       $sep = ':';
+               }
+               $arr['postopts'] = $postopts;
+       }
+}
+
 function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) {
 
        // If it is a posting where users should get notifications, then define it as wall posting
@@ -1153,6 +1196,24 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
                }
        }
 
+       // Do we already have this item?
+       // We have to check several networks since Friendica posts could be repeated via OStatus (maybe Diasporsa as well)
+       if (in_array(trim($arr['network']), array(NETWORK_DIASPORA, NETWORK_DFRN, NETWORK_OSTATUS, ""))) {
+               $r = q("SELECT `id`, `network` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` IN ('%s', '%s', '%s')  LIMIT 1",
+                               dbesc(trim($arr['uri'])),
+                               intval($uid),
+                               dbesc(NETWORK_DIASPORA),
+                               dbesc(NETWORK_DFRN),
+                               dbesc(NETWORK_OSTATUS)
+                       );
+               if ($r) {
+                       // We only log the entries with a different user id than 0. Otherwise we would have too many false positives
+                       if ($uid != 0)
+                               logger("Item with uri ".$arr['uri']." already existed for user ".$uid." with id ".$r[0]["id"]." target network ".$r[0]["network"]." - new network: ".$arr['network']);
+                       return($r[0]["id"]);
+               }
+       }
+
        // If there is no guid then take the same guid that was taken before for the same uri
        if ((trim($arr['guid']) == "") AND (trim($arr['uri']) != "") AND (trim($arr['network']) != "")) {
                logger('item_store: checking for an existing guid for uri '.$arr['uri'], LOGGER_DEBUG);
@@ -1185,37 +1246,23 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        //if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false))
        //      $arr['body'] = strip_tags($arr['body']);
 
+       item_add_language_opt($arr);
 
-       if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
-               require_once('library/langdet/Text/LanguageDetect.php');
-               $naked_body = preg_replace('/\[(.+?)\]/','',$arr['body']);
-               $l = new Text_LanguageDetect;
-               //$lng = $l->detectConfidence($naked_body);
-               //$arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
-               $lng = $l->detect($naked_body, 3);
-
-               if (sizeof($lng) > 0) {
-                       $postopts = "";
-
-                       foreach ($lng as $language => $score) {
-                               if ($postopts == "")
-                                       $postopts = "lang=";
-                               else
-                                       $postopts .= ":";
-
-                               $postopts .= $language.";".$score;
-                       }
-                       $arr['postopts'] = $postopts;
-               }
+       if ($notify)
+               $guid_prefix = "";
+       else {
+               $parsed = parse_url($arr["author-link"]);
+               $guid_prefix = hash("crc32", $parsed["host"]);
        }
 
        $arr['wall']          = ((x($arr,'wall'))          ? intval($arr['wall'])                : 0);
-       $arr['uri']           = ((x($arr,'uri'))           ? notags(trim($arr['uri']))           : random_string());
+       $arr['guid']          = ((x($arr,'guid'))          ? notags(trim($arr['guid']))          : get_guid(32, $guid_prefix));
+       $arr['uri']           = ((x($arr,'uri'))           ? notags(trim($arr['uri']))           : $arr['guid']);
        $arr['extid']         = ((x($arr,'extid'))         ? notags(trim($arr['extid']))         : '');
-       $arr['author-name']   = ((x($arr,'author-name'))   ? notags(trim($arr['author-name']))   : '');
+       $arr['author-name']   = ((x($arr,'author-name'))   ? trim($arr['author-name'])   : '');
        $arr['author-link']   = ((x($arr,'author-link'))   ? notags(trim($arr['author-link']))   : '');
        $arr['author-avatar'] = ((x($arr,'author-avatar')) ? notags(trim($arr['author-avatar'])) : '');
-       $arr['owner-name']    = ((x($arr,'owner-name'))    ? notags(trim($arr['owner-name']))    : '');
+       $arr['owner-name']    = ((x($arr,'owner-name'))    ? trim($arr['owner-name'])    : '');
        $arr['owner-link']    = ((x($arr,'owner-link'))    ? notags(trim($arr['owner-link']))    : '');
        $arr['owner-avatar']  = ((x($arr,'owner-avatar'))  ? notags(trim($arr['owner-avatar']))  : '');
        $arr['created']       = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert());
@@ -1223,8 +1270,8 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        $arr['commented']     = ((x($arr,'commented')  !== false) ? datetime_convert('UTC','UTC',$arr['commented'])  : datetime_convert());
        $arr['received']      = ((x($arr,'received')  !== false) ? datetime_convert('UTC','UTC',$arr['received'])  : datetime_convert());
        $arr['changed']       = ((x($arr,'changed')  !== false) ? datetime_convert('UTC','UTC',$arr['changed'])  : datetime_convert());
-       $arr['title']         = ((x($arr,'title'))         ? notags(trim($arr['title']))         : '');
-       $arr['location']      = ((x($arr,'location'))      ? notags(trim($arr['location']))      : '');
+       $arr['title']         = ((x($arr,'title'))         ? trim($arr['title'])         : '');
+       $arr['location']      = ((x($arr,'location'))      ? trim($arr['location'])      : '');
        $arr['coord']         = ((x($arr,'coord'))         ? notags(trim($arr['coord']))         : '');
        $arr['last-child']    = ((x($arr,'last-child'))    ? intval($arr['last-child'])          : 0 );
        $arr['visible']       = ((x($arr,'visible') !== false) ? intval($arr['visible'])         : 1 );
@@ -1248,7 +1295,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        $arr['app']           = ((x($arr,'app'))           ? notags(trim($arr['app']))           : '');
        $arr['origin']        = ((x($arr,'origin'))        ? intval($arr['origin'])              : 0 );
        $arr['network']       = ((x($arr,'network'))       ? trim($arr['network'])               : '');
-       $arr['guid']          = ((x($arr,'guid'))          ? notags(trim($arr['guid']))          : get_guid(32, $arr['network']));
        $arr['postopts']      = ((x($arr,'postopts'))      ? trim($arr['postopts'])              : '');
        $arr['resource-id']   = ((x($arr,'resource-id'))   ? trim($arr['resource-id'])           : '');
        $arr['event-id']      = ((x($arr,'event-id'))      ? intval($arr['event-id'])            : 0 );
@@ -1261,11 +1307,24 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        }
 
        if ($arr['network'] == "") {
-               $r = q("SELECT `network` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
-                       intval($arr['contact-id']),
+               $r = q("SELECT `network` FROM `contact` WHERE `network` IN ('%s', '%s', '%s') AND `nurl` = '%s' AND `uid` = %d LIMIT 1",
+                       dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS),
+                       dbesc(normalise_link($arr['author-link'])),
                        intval($arr['uid'])
                );
 
+               if(!count($r))
+                       $r = q("SELECT `network` FROM `gcontact` WHERE `network` IN ('%s', '%s', '%s') AND `nurl` = '%s' LIMIT 1",
+                               dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS),
+                               dbesc(normalise_link($arr['author-link']))
+                       );
+
+               if(!count($r))
+                       $r = q("SELECT `network` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+                               intval($arr['contact-id']),
+                               intval($arr['uid'])
+                       );
+
                if(count($r))
                        $arr['network'] = $r[0]["network"];
 
@@ -1386,9 +1445,10 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
                }
        }
 
-       $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1",
+       $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `network` IN ('%s', '%s') AND `uid` = %d LIMIT 1",
                dbesc($arr['uri']),
                dbesc($arr['network']),
+               dbesc(NETWORK_DFRN),
                intval($arr['uid'])
        );
        if($r && count($r)) {
@@ -1423,7 +1483,10 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        // Fill the cache field
        put_item_in_cache($arr);
 
-       call_hooks('post_remote',$arr);
+       if ($notify)
+               call_hooks('post_local',$arr);
+       else
+               call_hooks('post_remote',$arr);
 
        if(x($arr,'cancel')) {
                logger('item_store: post cancelled by plugin.');
@@ -1446,13 +1509,24 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
        // And restore it
        $arr = $unescaped;
 
-       // find the item we just created
-       $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d ORDER BY `id` ASC ",
+       // find the item that we just created
+       $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s' ORDER BY `id` ASC",
                dbesc($arr['uri']),
-               intval($arr['uid'])
+               intval($arr['uid']),
+               dbesc($arr['network'])
        );
 
-       if(count($r)) {
+       if(count($r) > 1) {
+               // There are duplicates. Keep the oldest one, delete the others
+               logger('item_store: duplicated post occurred. Removing newer duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']);
+               q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s' AND `id` > %d",
+                       dbesc($arr['uri']),
+                       intval($arr['uid']),
+                       dbesc($arr['network']),
+                       intval($r[0]["id"])
+               );
+               return 0;
+       } elseif(count($r)) {
 
                // Store the guid and other relevant data
                add_guid($arr);
@@ -1485,14 +1559,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
                logger('item_store: could not locate created item');
                return 0;
        }
-       if(count($r) > 1) {
-               logger('item_store: duplicated post occurred. Removing duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']);
-               q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `id` != %d ",
-                       dbesc($arr['uri']),
-                       intval($arr['uid']),
-                       intval($current_post)
-               );
-       }
 
        if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))
                $parent_id = $current_post;
@@ -1569,7 +1635,10 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
 
                $r = q('SELECT * FROM `item` WHERE id = %d', intval($current_post));
                if (count($r) == 1) {
-                       call_hooks('post_remote_end', $r[0]);
+                       if ($notify)
+                               call_hooks('post_local_end', $r[0]);
+                       else
+                               call_hooks('post_remote_end', $r[0]);
                } else
                        logger('item_store: new item not found in DB, id ' . $current_post);
        }
@@ -1986,13 +2055,14 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
        if($contact['duplex'] && $contact['issued-id'])
                $idtosend = '1:' . $orig_id;
 
-    
+
        $rino = get_config('system','rino_encrypt');
        $rino = intval($rino);
+       // use RINO1 if mcrypt isn't installed and RINO2 was selected
+       if ($rino==2 and !function_exists('mcrypt_create_iv')) $rino=1;
 
-   
+       logger("Local rino version: ". $rino, LOGGER_DEBUG);
 
-       
        $ssl_val = intval(get_config('system','ssl_policy'));
        $ssl_policy = '';
 
@@ -2043,6 +2113,8 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
        $rino_remote_version = intval($res->rino);
        $page         = (($owner['page-flags'] == PAGE_COMMUNITY) ? 1 : 0);
 
+       logger("Remote rino version: ".$rino_remote_version." for ".$contact["url"], LOGGER_DEBUG);
+
        if($owner['page-flags'] == PAGE_PRVGROUP)
                $page = 2;
 
@@ -2120,26 +2192,26 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
                                        return -1;
                                } catch (CannotPerformOperation $ex) {
                                        logger('Cannot safely create a key');
-                                       return -1; 
+                                       return -1;
                                }
                                try {
                                        $data = Crypto::encrypt($postvars['data'], $key);
                                } catch (CryptoTestFailed $ex) {
                                        logger('Cannot safely perform encryption');
-                                       return -1; 
+                                       return -1;
                                } catch (CannotPerformOperation $ex) {
                                        logger('Cannot safely perform encryption');
-                                       return -1; 
+                                       return -1;
                                }
                                break;
                        default:
                                logger("rino: invalid requested verision '$rino_remote_version'");
                                return -1;
                }
-               
+
                $postvars['rino'] = $rino_remote_version;
                $postvars['data'] = bin2hex($data);
-               
+
                #logger('rino: sent key = ' . $key, LOGGER_DEBUG);
 
 
@@ -2167,7 +2239,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
 
                $postvars['key'] = bin2hex($postvars['key']);
        }
-       
+
 
        logger('dfrn_deliver: ' . "SENDING: " . print_r($postvars,true), LOGGER_DATA);
 
@@ -2251,15 +2323,22 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
        if ($contact['network'] === NETWORK_OSTATUS) {
                if ($pass < 2) {
                        // Test - remove before flight
-                       //$tempfile = tempnam(get_temppath(), "ostatus");
+                       //$tempfile = tempnam(get_temppath(), "ostatus2");
                        //file_put_contents($tempfile, $xml);
-
                        logger("Consume OStatus messages ", LOGGER_DEBUG);
                        ostatus_import($xml,$importer,$contact, $hub);
                }
                return;
        }
 
+       if ($contact['network'] === NETWORK_FEED) {
+               if ($pass < 2) {
+                       logger("Consume feeds", LOGGER_DEBUG);
+                       feed_import($xml,$importer,$contact, $hub);
+               }
+               return;
+       }
+
        require_once('library/simplepie/simplepie.inc');
        require_once('include/contact_selectors.php');
 
@@ -2328,85 +2407,45 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                $contact_updated = $photo_timestamp;
 
                require_once("include/Photo.php");
-               $photo_failure = false;
-               $have_photo = false;
+               $photos = import_profile_photo($photo_url,$contact['uid'],$contact['id']);
 
-               $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1",
-                       intval($contact['id']),
-                       intval($contact['uid'])
+               q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
+                       WHERE `uid` = %d AND `id` = %d AND NOT `self`",
+                       dbesc(datetime_convert()),
+                       dbesc($photos[0]),
+                       dbesc($photos[1]),
+                       dbesc($photos[2]),
+                       intval($contact['uid']),
+                       intval($contact['id'])
                );
-               if(count($r)) {
-                       $resource_id = $r[0]['resource-id'];
-                       $have_photo = true;
-               }
-               else {
-                       $resource_id = photo_new_resource();
-               }
-
-               $img_str = fetch_url($photo_url,true);
-               // guess mimetype from headers or filename
-               $type = guess_image_type($photo_url,true);
-
-
-               $img = new Photo($img_str, $type);
-               if($img->is_valid()) {
-                       if($have_photo) {
-                               q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d",
-                                       dbesc($resource_id),
-                                       intval($contact['id']),
-                                       intval($contact['uid'])
-                               );
-                       }
-
-                       $img->scaleImageSquare(175);
-
-                       $hash = $resource_id;
-                       $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4);
-
-                       $img->scaleImage(80);
-                       $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5);
-
-                       $img->scaleImage(48);
-                       $r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 6);
-
-                       $a = get_app();
-
-                       q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
-                               WHERE `uid` = %d AND `id` = %d",
-                               dbesc(datetime_convert()),
-                               dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()),
-                               dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.'.$img->getExt()),
-                               dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.'.$img->getExt()),
-                               intval($contact['uid']),
-                               intval($contact['id'])
-                       );
-               }
        }
 
        if((is_array($contact)) && ($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) {
                if ($name_updated > $contact_updated)
                        $contact_updated = $name_updated;
 
-               $r = q("select * from contact where uid = %d and id = %d limit 1",
+               $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
                        intval($contact['uid']),
                        intval($contact['id'])
                );
 
-               $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d",
+               $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`",
                        dbesc(notags(trim($new_name))),
                        dbesc(datetime_convert()),
                        intval($contact['uid']),
-                       intval($contact['id'])
+                       intval($contact['id']),
+                       dbesc(notags(trim($new_name)))
                );
 
                // do our best to update the name on content items
 
-               if(count($r)) {
-                       q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d",
+               if(count($r) AND (notags(trim($new_name)) != $r[0]['name'])) {
+                       q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'",
                                dbesc(notags(trim($new_name))),
                                dbesc($r[0]['name']),
                                dbesc($r[0]['url']),
-                               intval($contact['uid'])
+                               intval($contact['uid']),
+                               dbesc(notags(trim($new_name)))
                        );
                }
        }
@@ -2505,6 +2544,11 @@ 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['object-type'] === ACTIVITY_OBJ_EVENT) {
+                                               logger("Deleting event ".$item['event-id'], LOGGER_DEBUG);
+                                               event_delete($item['event-id']);
+                                       }
+
                                        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);
@@ -2712,7 +2756,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                                $datarray['parent-uri'] = $parent_uri;
                                $datarray['uid'] = $importer['uid'];
                                $datarray['contact-id'] = $contact['id'];
-                               if((activity_match($datarray['verb'],ACTIVITY_LIKE)) || (activity_match($datarray['verb'],ACTIVITY_DISLIKE))) {
+                               if(($datarray['verb'] === ACTIVITY_LIKE)
+                                       || ($datarray['verb'] === ACTIVITY_DISLIKE)
+                                       || ($datarray['verb'] === ACTIVITY_ATTEND)
+                                       || ($datarray['verb'] === ACTIVITY_ATTENDNO)
+                                       || ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
                                        $datarray['type'] = 'activity';
                                        $datarray['gravity'] = GRAVITY_LIKE;
                                        // only one like or dislike per person
@@ -2792,11 +2840,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
 
                                if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) {
                                        $ev = bbtoevent($datarray['body']);
-                                       if(x($ev,'desc') && x($ev,'start')) {
+                                       if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
                                                $ev['uid'] = $importer['uid'];
                                                $ev['uri'] = $item_id;
                                                $ev['edited'] = $datarray['edited'];
                                                $ev['private'] = $datarray['private'];
+                                               $ev['guid'] = $datarray['guid'];
 
                                                if(is_array($contact))
                                                        $ev['cid'] = $contact['id'];
@@ -3056,85 +3105,46 @@ function local_delivery($importer,$data) {
 
                logger('local_delivery: Updating photo for ' . $importer['name']);
                require_once("include/Photo.php");
-               $photo_failure = false;
-               $have_photo = false;
-
-               $r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1",
-                       intval($importer['id']),
-                       intval($importer['importer_uid'])
-               );
-               if(count($r)) {
-                       $resource_id = $r[0]['resource-id'];
-                       $have_photo = true;
-               }
-               else {
-                       $resource_id = photo_new_resource();
-               }
-
-               $img_str = fetch_url($photo_url,true);
-               // guess mimetype from headers or filename
-               $type = guess_image_type($photo_url,true);
-
-
-               $img = new Photo($img_str, $type);
-               if($img->is_valid()) {
-                       if($have_photo) {
-                               q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d",
-                                       dbesc($resource_id),
-                                       intval($importer['id']),
-                                       intval($importer['importer_uid'])
-                               );
-                       }
-
-                       $img->scaleImageSquare(175);
-
-                       $hash = $resource_id;
-                       $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 4);
 
-                       $img->scaleImage(80);
-                       $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 5);
+               $photos = import_profile_photo($photo_url,$importer['importer_uid'],$importer['id']);
 
-                       $img->scaleImage(48);
-                       $r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 6);
-
-                       $a = get_app();
-
-                       q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
-                               WHERE `uid` = %d AND `id` = %d",
-                               dbesc(datetime_convert()),
-                               dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()),
-                               dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.'.$img->getExt()),
-                               dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.'.$img->getExt()),
-                               intval($importer['importer_uid']),
-                               intval($importer['id'])
-                       );
-               }
+               q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
+                       WHERE `uid` = %d AND `id` = %d AND NOT `self`",
+                       dbesc(datetime_convert()),
+                       dbesc($photos[0]),
+                       dbesc($photos[1]),
+                       dbesc($photos[2]),
+                       intval($importer['importer_uid']),
+                       intval($importer['id'])
+               );
        }
 
        if(($name_updated) && (strlen($new_name)) && ($name_updated > $importer['name-date'])) {
                if ($name_updated > $contact_updated)
                        $contact_updated = $name_updated;
 
-               $r = q("select * from contact where uid = %d and id = %d limit 1",
+               $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
                        intval($importer['importer_uid']),
                        intval($importer['id'])
                );
 
-               $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d",
+               $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`",
                        dbesc(notags(trim($new_name))),
                        dbesc(datetime_convert()),
                        intval($importer['importer_uid']),
-                       intval($importer['id'])
+                       intval($importer['id']),
+                       dbesc(notags(trim($new_name)))
                );
 
                // do our best to update the name on content items
 
-               if(count($r)) {
-                       q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d",
+               if(count($r) AND (notags(trim($new_name)) != $r[0]['name'])) {
+                       q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'",
                                dbesc(notags(trim($new_name))),
                                dbesc($r[0]['name']),
                                dbesc($r[0]['url']),
-                               intval($importer['importer_uid'])
+                               intval($importer['importer_uid']),
+                               dbesc(notags(trim($new_name)))
                        );
                }
        }
@@ -3486,6 +3496,11 @@ function local_delivery($importer,$data) {
 
                                        logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
 
+                                       if($item['object-type'] === ACTIVITY_OBJ_EVENT) {
+                                               logger("Deleting event ".$item['event-id'], LOGGER_DEBUG);
+                                               event_delete($item['event-id']);
+                                       }
+
                                        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);
@@ -3699,7 +3714,11 @@ function local_delivery($importer,$data) {
                                $datarray['owner-avatar'] = $own[0]['thumb'];
                                $datarray['contact-id'] = $importer['id'];
 
-                               if(($datarray['verb'] === ACTIVITY_LIKE) || ($datarray['verb'] === ACTIVITY_DISLIKE)) {
+                               if(($datarray['verb'] === ACTIVITY_LIKE) 
+                                       || ($datarray['verb'] === ACTIVITY_DISLIKE)
+                                       || ($datarray['verb'] === ACTIVITY_ATTEND)
+                                       || ($datarray['verb'] === ACTIVITY_ATTENDNO)
+                                       || ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
                                        $is_like = true;
                                        $datarray['type'] = 'activity';
                                        $datarray['gravity'] = GRAVITY_LIKE;
@@ -3888,7 +3907,11 @@ function local_delivery($importer,$data) {
                                $datarray['parent-uri'] = $parent_uri;
                                $datarray['uid'] = $importer['importer_uid'];
                                $datarray['contact-id'] = $importer['id'];
-                               if(($datarray['verb'] == ACTIVITY_LIKE) || ($datarray['verb'] == ACTIVITY_DISLIKE)) {
+                               if(($datarray['verb'] === ACTIVITY_LIKE) 
+                                       || ($datarray['verb'] === ACTIVITY_DISLIKE)
+                                       || ($datarray['verb'] === ACTIVITY_ATTEND)
+                                       || ($datarray['verb'] === ACTIVITY_ATTENDNO)
+                                       || ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
                                        $datarray['type'] = 'activity';
                                        $datarray['gravity'] = GRAVITY_LIKE;
                                        // only one like or dislike per person
@@ -4008,12 +4031,13 @@ function local_delivery($importer,$data) {
 
                        if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) {
                                $ev = bbtoevent($datarray['body']);
-                               if(x($ev,'desc') && x($ev,'start')) {
+                               if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
                                        $ev['cid'] = $importer['id'];
                                        $ev['uid'] = $importer['uid'];
                                        $ev['uri'] = $item_id;
                                        $ev['edited'] = $datarray['edited'];
                                        $ev['private'] = $datarray['private'];
+                                       $ev['guid'] = $datarray['guid'];
 
                                        $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
                                                dbesc($item_id),
@@ -4173,14 +4197,13 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
                        );
                }
                // send email notification to owner?
-       }
-       else {
+       } else {
 
                // create contact record
 
-               $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`,
-                       `blocked`, `readonly`, `pending`, `writable` )
-                       VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, 1 ) ",
+               $r = q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`,
+                       `blocked`, `readonly`, `pending`, `writable`)
+                       VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, 1)",
                        intval($importer['uid']),
                        dbesc(datetime_convert()),
                        dbesc($url),
@@ -4195,27 +4218,38 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
                                intval($importer['uid']),
                                dbesc($url)
                );
-               if(count($r))
+               if(count($r)) {
                                $contact_record = $r[0];
 
-               // create notification
-               $hash = random_string();
+                               $photos = import_profile_photo($photo,$importer["uid"],$contact_record["id"]);
 
-               if(is_array($contact_record)) {
-                       $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `hash`, `datetime`)
-                               VALUES ( %d, %d, 0, 0, '%s', '%s' )",
-                               intval($importer['uid']),
-                               intval($contact_record['id']),
-                               dbesc($hash),
-                               dbesc(datetime_convert())
-                       );
+                               q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `id` = %d",
+                                       dbesc($photos[0]),
+                                       dbesc($photos[1]),
+                                       dbesc($photos[2]),
+                                       intval($contact_record["id"])
+                               );
                }
 
+
                $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
                        intval($importer['uid'])
                );
                $a = get_app();
-               if(count($r)) {
+               if(count($r) AND !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
+
+                       // create notification
+                       $hash = random_string();
+
+                       if(is_array($contact_record)) {
+                               $ret = q("INSERT INTO `intro` ( `uid`, `contact-id`, `blocked`, `knowyou`, `hash`, `datetime`)
+                                       VALUES ( %d, %d, 0, 0, '%s', '%s' )",
+                                       intval($importer['uid']),
+                                       intval($contact_record['id']),
+                                       dbesc($hash),
+                                       dbesc(datetime_convert())
+                               );
+                       }
 
                        if(intval($r[0]['def_gid'])) {
                                require_once('include/group.php');
@@ -4223,7 +4257,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
                        }
 
                        if(($r[0]['notify-flags'] & NOTIFY_INTRO) &&
-                               in_array($r[0]['page-flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) {
+                               in_array($r[0]['page-flags'], array(PAGE_NORMAL))) {
 
                                notification(array(
                                        'type'         => NOTIFY_INTRO,
@@ -4241,7 +4275,13 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
                                ));
 
                        }
+               } elseif (count($r) AND in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
+                       $r = q("UPDATE `contact` SET `pending` = 0 WHERE `uid` = %d AND `url` = '%s' AND `pending` LIMIT 1",
+                                       intval($importer['uid']),
+                                       dbesc($url)
+                       );
                }
+
        }
 }
 
@@ -4299,7 +4339,7 @@ function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') {
 
        logger('subscribe_to_hub: ' . $hubmode . ' ' . $contact['name'] . ' to hub ' . $url . ' endpoint: '  . $push_url . ' with verifier ' . $verify_token);
 
-       if(! strlen($contact['hub-verify'])) {
+       if(!strlen($contact['hub-verify']) OR ($contact['hub-verify'] != $verify_token)) {
                $r = q("UPDATE `contact` SET `hub-verify` = '%s' WHERE `id` = %d",
                        dbesc($verify_token),
                        intval($contact['id'])
@@ -4315,7 +4355,7 @@ function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') {
 }
 
 
-function atom_author($tag,$name,$uri,$h,$w,$photo) {
+function atom_author($tag,$name,$uri,$h,$w,$photo,$geo) {
        $o = '';
        if(! $tag)
                return $o;
@@ -4333,6 +4373,10 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) {
        $o .= "\t".'<link rel="avatar" type="image/jpeg" media:width="' . $w . '" media:height="' . $h . '" href="' . $photo . '" />' . "\r\n";
 
        if ($tag == "author") {
+
+               if($geo)
+                       $o .= '<georss:point>'.xmlify($geo).'</georss:point>'."\r\n";
+
                $r = q("SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`,
                                `profile`.`name`, `profile`.`pub_keywords`, `profile`.`about`,
                                `profile`.`homepage`,`contact`.`nick` FROM `profile`
@@ -4358,7 +4402,7 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) {
 
                        $o .= "\t<poco:preferredUsername>".xmlify($r[0]["nick"])."</poco:preferredUsername>\r\n";
                        $o .= "\t<poco:displayName>".xmlify($r[0]["name"])."</poco:displayName>\r\n";
-                       $o .= "\t<poco:note>".xmlify($r[0]["about"])."</poco:note>\r\n";
+                       $o .= "\t<poco:note>".xmlify(bbcode($r[0]["about"]))."</poco:note>\r\n";
                        $o .= "\t<poco:address>\r\n";
                        $o .= "\t\t<poco:formatted>".xmlify($location)."</poco:formatted>\r\n";
                        $o .= "\t</poco:address>\r\n";
@@ -4396,11 +4440,11 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
        $o = "\r\n\r\n<entry>\r\n";
 
        if(is_array($author))
-               $o .= atom_author('author',$author['name'],$author['url'],80,80,$author['thumb']);
+               $o .= atom_author('author',$author['name'],$author['url'],80,80,$author['thumb'], $item['coord']);
        else
-               $o .= atom_author('author',(($item['author-name']) ? $item['author-name'] : $item['name']),(($item['author-link']) ? $item['author-link'] : $item['url']),80,80,(($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']));
+               $o .= atom_author('author',(($item['author-name']) ? $item['author-name'] : $item['name']),(($item['author-link']) ? $item['author-link'] : $item['url']),80,80,(($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']), $item['coord']);
        if(strlen($item['owner-name']))
-               $o .= atom_author('dfrn:owner',$item['owner-name'],$item['owner-link'],80,80,$item['owner-avatar']);
+               $o .= atom_author('dfrn:owner',$item['owner-name'],$item['owner-link'],80,80,$item['owner-avatar'], $item['coord']);
 
        if(($item['parent'] != $item['id']) || ($item['parent-uri'] !== $item['uri']) || (($item['thr-parent'] !== '') && ($item['thr-parent'] !== $item['uri']))) {
                $parent = q("SELECT `guid` FROM `item` WHERE `id` = %d", intval($item["parent"]));
@@ -4477,7 +4521,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
        //$o .= "\t".'<link rel="self" type="application/atom+xml" href="'.xmlify($a->get_baseurl().'/api/statuses/show/'.$item['id'].'.atom').'"/>'."\r\n";
        //$o .= "\t".'<link rel="edit" type="application/atom+xml" href="'.xmlify($a->get_baseurl().'/api/statuses/show/'.$item['id'].'.atom').'"/>'."\r\n";
 
-       $o .= item_get_attachment($item);
+       // Deactivated since it was meant only for OStatus
+       //$o .= item_get_attachment($item);
 
        $o .= item_getfeedattach($item);
 
@@ -4642,7 +4687,7 @@ function item_getfeedtags($item) {
        if($cnt) {
                for($x = 0; $x < $cnt; $x ++) {
                        if($matches[1][$x])
-                               $ret[] = array('#',$matches[1][$x], $matches[2][$x]);
+                               $ret[$matches[2][$x]] = array('#',$matches[1][$x], $matches[2][$x]);
                }
        }
        $matches = false;