]> git.mxchange.org Git - friendica.git/blobdiff - include/items.php
Remote-self: It is now possible to chose between two different modes of mirroring.
[friendica.git] / include / items.php
old mode 100755 (executable)
new mode 100644 (file)
index f3fd4a9..0df200a
@@ -678,6 +678,10 @@ function get_atom_elements($feed, $item, $contact = array()) {
        if($rawgeo)
                $res['coord'] = unxmlify($rawgeo[0]['data']);
 
+       if ($contact["network"] == NETWORK_FEED) {
+               $res['verb'] = ACTIVITY_POST;
+               $res['object-type'] = ACTIVITY_OBJ_NOTE;
+       }
 
        $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
 
@@ -864,6 +868,7 @@ function get_atom_elements($feed, $item, $contact = array()) {
        if (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND $contact['fetch_further_information']) {
                $res["body"] = $res["title"].add_page_info($res['plink']);
                $res["title"] = "";
+               $res["object-type"] = ACTIVITY_OBJ_BOOKMARK;
        } elseif (isset($contact["network"]) AND ($contact["network"] == NETWORK_OSTATUS))
                $res["body"] = add_page_info_to_body($res["body"]);
        elseif (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND strstr($res['plink'], ".app.net/")) {
@@ -874,21 +879,15 @@ function get_atom_elements($feed, $item, $contact = array()) {
 
        call_hooks('parse_atom', $arr);
 
-       //if (($res["title"] != "") or (strpos($res["body"], "RT @") > 0)) {
-       //if (strpos($res["body"], "RT @") !== false) {
-       /*if (strpos($res["body"], "@") !== false) {
-               $debugfile = tempnam("/var/www/virtual/pirati.ca/phptmp/", "item-res2-");
-               file_put_contents($debugfile, serialize($arr));
-       }*/
-
        return $res;
 }
 
 function add_page_info($url, $no_photos = false, $photo = "") {
-        require_once("mod/parse_url.php");
-        $data = parseurl_getsiteinfo($url, true);
+       require_once("mod/parse_url.php");
+
+       $data = parseurl_getsiteinfo($url, true);
 
-        logger('add_page_info: fetch page info for '.$url.' '.print_r($data, true), LOGGER_DEBUG);
+       logger('add_page_info: fetch page info for '.$url.' '.print_r($data, true), LOGGER_DEBUG);
 
        // It maybe is a rich content, but if it does have everything that a link has,
        // then treat it that way
@@ -896,53 +895,69 @@ function add_page_info($url, $no_photos = false, $photo = "") {
                is_string($data["text"]) AND (sizeof($data["images"]) > 0))
                $data["type"] = "link";
 
-        if ((($data["type"] != "link") AND ($data["type"] != "video") AND ($data["type"] != "photo")) OR ($data["title"] == $url))
-                return("");
+       if ((($data["type"] != "link") AND ($data["type"] != "video") AND ($data["type"] != "photo")) OR ($data["title"] == $url))
+               return("");
 
        if ($no_photos AND ($data["type"] == "photo"))
                return("");
 
-        if (($data["type"] != "photo") AND is_string($data["title"]))
-                $text .= "[bookmark=".$url."]".trim($data["title"])."[/bookmark]";
+       if (($data["type"] != "photo") AND is_string($data["title"]))
+               $text .= "[bookmark=".$url."]".trim($data["title"])."[/bookmark]";
 
-        if (($data["type"] != "video") AND ($photo != ""))
-                $text .= '[img]'.$photo.'[/img]';
-        elseif (($data["type"] != "video") AND (sizeof($data["images"]) > 0)) {
-                $imagedata = $data["images"][0];
-                $text .= '[img]'.$imagedata["src"].'[/img]';
-        }
+       if (($data["type"] != "video") AND ($photo != ""))
+               $text .= '[img]'.$photo.'[/img]';
+       elseif (($data["type"] != "video") AND (sizeof($data["images"]) > 0)) {
+               $imagedata = $data["images"][0];
+               $text .= '[img]'.$imagedata["src"].'[/img]';
+       }
 
-        if (($data["type"] != "photo") AND is_string($data["text"]))
-                $text .= "[quote]".$data["text"]."[/quote]";
+       if (($data["type"] != "photo") AND is_string($data["text"]))
+               $text .= "[quote]".$data["text"]."[/quote]";
 
-        return("\n[class=type-".$data["type"]."]".$text."[/class]");
+       return("\n[class=type-".$data["type"]."]".$text."[/class]");
 }
 
 function add_page_info_to_body($body, $texturl = false, $no_photos = false) {
 
-        logger('add_page_info_to_body: fetch page info for body '.$body, LOGGER_DEBUG);
+       logger('add_page_info_to_body: fetch page info for body '.$body, LOGGER_DEBUG);
 
-        $URLSearchString = "^\[\]";
+       $URLSearchString = "^\[\]";
 
-        // Adding these spaces is a quick hack due to my problems with regular expressions :)
-        preg_match("/[^!#@]\[url\]([$URLSearchString]*)\[\/url\]/ism", " ".$body, $matches);
+       // Adding these spaces is a quick hack due to my problems with regular expressions :)
+       preg_match("/[^!#@]\[url\]([$URLSearchString]*)\[\/url\]/ism", " ".$body, $matches);
 
-        if (!$matches)
-                preg_match("/[^!#@]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", " ".$body, $matches);
+       if (!$matches)
+               preg_match("/[^!#@]\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", " ".$body, $matches);
 
        // Convert urls without bbcode elements
        if (!$matches AND $texturl) {
                preg_match("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", " ".$body, $matches);
 
                // Yeah, a hack. I really hate regular expressions :)
-               if ($matches)
-                       $matches[1] = $matches[2];
+               if ($matches)
+                       $matches[1] = $matches[2];
        }
 
-        if ($matches)
-                $body .= add_page_info($matches[1], $no_photos);
+       if ($matches)
+               $footer = add_page_info($matches[1], $no_photos);
 
-        return $body;
+       // Remove the link from the body if the link is attached at the end of the post
+       if (isset($footer) AND (trim($footer) != "") AND (strpos($footer, $matches[1]))) {
+               $removedlink = trim(str_replace($matches[1], "", $body));
+               if (($removedlink == "") OR strstr($body, $removedlink))
+                       $body = $removedlink;
+
+               $url = str_replace(array('/', '.'), array('\/', '\.'), $matches[1]);
+               $removedlink = preg_replace("/\[url\=".$url."\](.*?)\[\/url\]/ism", '', $body);
+               if (($removedlink == "") OR strstr($body, $removedlink))
+                       $body = $removedlink;
+       }
+
+       // Add the page information to the bottom
+       if (isset($footer) AND (trim($footer) != ""))
+               $body .= $footer;
+
+       return $body;
 }
 
 function encode_rel_links($links) {
@@ -968,7 +983,7 @@ function encode_rel_links($links) {
 
 
 
-function item_store($arr,$force_parent = false) {
+function item_store($arr,$force_parent = false, $notify = false) {
 
        // If a Diaspora signature structure was passed in, pull it out of the
        // item array and set it aside for later storage.
@@ -985,7 +1000,7 @@ function item_store($arr,$force_parent = false) {
 
        if (isset($arr["ostatus_conversation"])) {
                $ostatus_conversation = $arr["ostatus_conversation"];
-               unset($arr["ostatus_conversation"]);
+               unset($arr["ostatus_conversation"]);
        }
 
        if(x($arr, 'gravity'))
@@ -1017,6 +1032,19 @@ function item_store($arr,$force_parent = false) {
                }
        }
 
+       // 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']) != "")) {
+               logger('item_store: checking for an existing guid for uri '.$arr['uri'], LOGGER_DEBUG);
+               $r = q("SELECT `guid` FROM `item` WHERE `uri` = '%s' AND `guid` != '' LIMIT 1",
+                       dbesc(trim($arr['uri']))
+               );
+
+               if(count($r)) {
+                       $arr['guid'] = $r[0]["guid"];
+                       logger('item_store: found guid '.$arr['guid'].' for uri '.$arr['uri'], LOGGER_DEBUG);
+               }
+       }
+
        // Shouldn't happen but we want to make absolutely sure it doesn't leak from a plugin.
        // Deactivated, since the bbcode parser can handle with it - and it destroys posts with some smileys that contain "<"
        //if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false))
@@ -1084,9 +1112,14 @@ function item_store($arr,$force_parent = false) {
        $arr['attach']        = ((x($arr,'attach'))        ? notags(trim($arr['attach']))        : '');
        $arr['app']           = ((x($arr,'app'))           ? notags(trim($arr['app']))           : '');
        $arr['origin']        = ((x($arr,'origin'))        ? intval($arr['origin'])              : 0 );
-       $arr['guid']          = ((x($arr,'guid'))          ? notags(trim($arr['guid']))          : get_guid());
+       $arr['guid']          = ((x($arr,'guid'))          ? notags(trim($arr['guid']))          : get_guid(30));
        $arr['network']       = ((x($arr,'network'))       ? trim($arr['network'])               : '');
 
+       if ($arr['plink'] == "") {
+               $a = get_app();
+               $arr['plink'] = $a->get_baseurl().'/display/'.urlencode($arr['guid']);
+       }
+
        if ($arr['network'] == "") {
                $r = q("SELECT `network` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
                        intval($arr['contact-id']),
@@ -1111,6 +1144,7 @@ function item_store($arr,$force_parent = false) {
                $allow_gid = $arr['allow_gid'];
                $deny_cid  = $arr['deny_cid'];
                $deny_gid  = $arr['deny_gid'];
+               $notify_type = 'wall-new';
        }
        else {
 
@@ -1147,6 +1181,7 @@ function item_store($arr,$force_parent = false) {
                        $deny_cid       = $r[0]['deny_cid'];
                        $deny_gid       = $r[0]['deny_gid'];
                        $arr['wall']    = $r[0]['wall'];
+                       $notify_type    = 'comment-new';
 
                        // if the parent is private, force privacy for the entire conversation
                        // This differs from the above settings as it subtly allows comments from
@@ -1247,7 +1282,7 @@ function item_store($arr,$force_parent = false) {
                        if(count($r)) {
                                logger('item_store: Send notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
                                $u = q("SELECT * FROM user WHERE uid = %d LIMIT 1",
-                                       intval($arr['uid']));
+                                       intval($arr['uid']));
 
                                $item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d",
                                        intval($current_post),
@@ -1265,7 +1300,7 @@ function item_store($arr,$force_parent = false) {
                                        'to_email'     => $u[0]['email'],
                                        'uid'          => $u[0]['uid'],
                                        'item'         => $item[0],
-                                       'link'         => $a->get_baseurl().'/display/'.$u[0]['nickname'].'/'.$current_post,
+                                       'link'         => $a->get_baseurl().'/display/'.urlencode($arr['guid']),
                                        'source_name'  => $item[0]['author-name'],
                                        'source_link'  => $item[0]['author-link'],
                                        'source_photo' => $item[0]['author-avatar'],
@@ -1292,7 +1327,7 @@ function item_store($arr,$force_parent = false) {
        if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))
                $parent_id = $current_post;
 
-       if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
+       if(strlen($allow_cid) || strlen($allow_gid) || strlen($deny_cid) || strlen($deny_gid))
                $private = 1;
        else
                $private = $arr['private'];
@@ -1315,14 +1350,14 @@ function item_store($arr,$force_parent = false) {
        if ($ostatus_conversation)
                complete_conversation($current_post, $ostatus_conversation);
 
-        $arr['id'] = $current_post;
-        $arr['parent'] = $parent_id;
-        $arr['allow_cid'] = $allow_cid;
-        $arr['allow_gid'] = $allow_gid;
-        $arr['deny_cid'] = $deny_cid;
-        $arr['deny_gid'] = $deny_gid;
-        $arr['private'] = $private;
-        $arr['deleted'] = $parent_deleted;
+       $arr['id'] = $current_post;
+       $arr['parent'] = $parent_id;
+       $arr['allow_cid'] = $allow_cid;
+       $arr['allow_gid'] = $allow_gid;
+       $arr['deny_cid'] = $deny_cid;
+       $arr['deny_gid'] = $deny_gid;
+       $arr['private'] = $private;
+       $arr['deleted'] = $parent_deleted;
 
        // update the commented timestamp on the parent
 
@@ -1384,8 +1419,55 @@ function item_store($arr,$force_parent = false) {
        create_tags_from_item($current_post);
        create_files_from_item($current_post);
 
+       if ($notify)
+               proc_run('php', "include/notifier.php", $notify_type, $current_post);
+
        return $current_post;
 }
+
+function get_item_guid($id) {
+       $r = q("SELECT `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($id));
+       if (count($r))
+               return($r[0]["guid"]);
+       else
+               return("");
+}
+
+function get_item_id($guid, $uid = 0) {
+
+       $nick = "";
+       $id = 0;
+
+       if ($uid == 0)
+               $uid == local_user();
+
+       // Does the given user have this item?
+       if ($uid) {
+               $r = q("SELECT `item`.`id`, `user`.`nickname` FROM `item` INNER JOIN `user` ON `user`.`uid` = `item`.`uid`
+                       WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
+                               AND `item`.`guid` = '%s' AND `item`.`uid` = %d", dbesc($guid), intval($uid));
+               if (count($r)) {
+                       $id = $r[0]["id"];
+                       $nick = $r[0]["nickname"];
+               }
+       }
+
+       // Or is it anywhere on the server?
+       if ($nick == "") {
+               $r = q("SELECT `item`.`id`, `user`.`nickname` FROM `item` INNER JOIN `user` ON `user`.`uid` = `item`.`uid`
+                       WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
+                               AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
+                               AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
+                               AND `item`.`private` = 0 AND `item`.`wall` = 1
+                               AND `item`.`guid` = '%s'", dbesc($guid));
+               if (count($r)) {
+                       $id = $r[0]["id"];
+                       $nick = $r[0]["nickname"];
+               }
+       }
+       return(array("nick" => $nick, "id" => $id));
+}
+
 // return - test
 function get_item_contact($item,$contacts) {
        if(! count($contacts) || (! is_array($item)))
@@ -1485,12 +1567,13 @@ function tag_deliver($uid,$item_id) {
                'to_email'     => $u[0]['email'],
                'uid'          => $u[0]['uid'],
                'item'         => $item,
-               'link'         => $a->get_baseurl() . '/display/' . $u[0]['nickname'] . '/' . $item['id'],
+               'link'         => $a->get_baseurl() . '/display/'.urlencode(get_item_guid($item['id'])),
                'source_name'  => $item['author-name'],
                'source_link'  => $item['author-link'],
                'source_photo' => $photo,
                'verb'         => ACTIVITY_TAG,
-               'otype'        => 'item'
+               'otype'        => 'item',
+               'parent'       => $item['parent']
        ));
 
 
@@ -1800,10 +1883,10 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
   */
 function edited_timestamp_is_newer($existing, $update) {
     if (!x($existing,'edited') || !$existing['edited']) {
-        return true;
+       return true;
     }
     if (!x($update,'edited') || !$update['edited']) {
-        return false;
+       return false;
     }
     $existing_edited = datetime_convert('UTC', 'UTC', $existing['edited']);
     $update_edited = datetime_convert('UTC', 'UTC', $update['edited']);
@@ -1893,7 +1976,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
        }
 
        if((is_array($contact)) && ($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $contact['avatar-date'])) {
-               logger('consume_feed: Updating photo for ' . $contact['name']);
+               logger('consume_feed: Updating photo for '.$contact['name'].' from '.$photo_url.' uid: '.$contact['uid']);
                require_once("include/Photo.php");
                $photo_failure = false;
                $have_photo = false;
@@ -1996,7 +2079,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                        $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`)
                                VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
                                intval($contact['uid']),
-                               intval($contact['id']),
+                               intval($contact['id']),
                                dbesc(datetime_convert()),
                                dbesc(datetime_convert()),
                                dbesc(datetime_convert('UTC','UTC', $birthday)),
@@ -2158,7 +2241,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
 
                logger('consume_feed: feed item count = ' . $feed->get_item_quantity());
 
-        // in inverse date order
+       // in inverse date order
                if ($datedir)
                        $items = array_reverse($feed->get_items());
                else
@@ -2454,16 +2537,6 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                                if($contact['network'] === NETWORK_FEED)
                                        $datarray['private'] = 2;
 
-                               // This is my contact on another system, but it's really me.
-                               // Turn this into a wall post.
-
-                               if($contact['remote_self']) {
-                                       $datarray['wall'] = 1;
-                                       if($contact['network'] === NETWORK_FEED) {
-                                               $datarray['private'] = 0;
-                                       }
-                               }
-
                                $datarray['parent-uri'] = $item_id;
                                $datarray['uid'] = $importer['uid'];
                                $datarray['contact-id'] = $contact['id'];
@@ -2486,8 +2559,36 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
                                if(($contact['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['uid'],$datarray)))
                                        continue;
 
+                               // This is my contact on another system, but it's really me.
+                               // Turn this into a wall post.
+
+                               if($contact['remote_self']) {
+                                       $datarray['wall'] = 1;
+
+                                       if ($contact['remote_self'] == 2) {
+                                               $r = q("SELECT `id`,`url`,`name`,`photo`,`network` FROM `contact` WHERE `uid` = %d AND `self`", intval($importer['uid']));
+                                               if (count($r)) {
+                                                       $datarray['contact-id'] = $r[0]["id"];
+                                                       $datarray['network'] = $r[0]["network"];
+
+                                                       $datarray['owner-name'] = $r[0]["name"];
+                                                       $datarray['owner-link'] = $r[0]["url"];
+                                                       $datarray['owner-avatar'] = $r[0]["photo"];
 
-                               $r = item_store($datarray);
+                                                       $datarray['author-name']   = $datarray['owner-name'];
+                                                       $datarray['author-link']   = $datarray['owner-link'];
+                                                       $datarray['author-avatar'] = $datarray['owner-avatar'];
+                                               }
+                                       }
+
+                                       $notify = true;
+                                       if($contact['network'] === NETWORK_FEED) {
+                                               $datarray['private'] = 0;
+                                       }
+                               } else
+                                       $notify = false;
+
+                               $r = item_store($datarray, false, $notify);
                                continue;
 
                        }
@@ -3300,7 +3401,7 @@ function local_delivery($importer,$data) {
                                                                'to_email'     => $importer['email'],
                                                                'uid'          => $importer['importer_uid'],
                                                                'item'         => $datarray,
-                                                               'link'             => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id,
+                                                               'link'             => $a->get_baseurl().'/display/'.urlencode(get_item_guid($posted_id)),
                                                                'source_name'  => stripslashes($datarray['author-name']),
                                                                'source_link'  => $datarray['author-link'],
                                                                'source_photo' => ((link_compare($datarray['author-link'],$importer['url']))
@@ -3464,7 +3565,7 @@ function local_delivery($importer,$data) {
                                                                        'to_email'     => $importer['email'],
                                                                        'uid'          => $importer['importer_uid'],
                                                                        'item'         => $datarray,
-                                                                       'link'             => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id,
+                                                                       'link'             => $a->get_baseurl().'/display/'.urlencode(get_item_guid($posted_id)),
                                                                        'source_name'  => stripslashes($datarray['author-name']),
                                                                        'source_link'  => $datarray['author-link'],
                                                                        'source_photo' => ((link_compare($datarray['author-link'],$importer['url']))
@@ -3555,12 +3656,6 @@ function local_delivery($importer,$data) {
                                continue;
                        }
 
-                       // This is my contact on another system, but it's really me.
-                       // Turn this into a wall post.
-
-                       if($importer['remote_self'])
-                               $datarray['wall'] = 1;
-
                        $datarray['parent-uri'] = $item_id;
                        $datarray['uid'] = $importer['importer_uid'];
                        $datarray['contact-id'] = $importer['id'];
@@ -3580,7 +3675,34 @@ function local_delivery($importer,$data) {
                        if(($importer['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['importer_uid'],$datarray)))
                                continue;
 
-                       $posted_id = item_store($datarray);
+                       // This is my contact on another system, but it's really me.
+                       // Turn this into a wall post.
+
+                       if($importer['remote_self']) {
+                               $datarray['wall'] = 1;
+
+                               if ($importer['remote_self'] == 2) {
+                                       $r = q("SELECT `id`,`url`,`name`,`photo`,`network` FROM `contact` WHERE `uid` = %d AND `self`",
+                                               intval($importer['importer_uid']));
+                                       if (count($r)) {
+                                               $datarray['contact-id'] = $r[0]["id"];
+                                               $datarray['network'] = $r[0]["network"];
+
+                                               $datarray['owner-name'] = $r[0]["name"];
+                                               $datarray['owner-link'] = $r[0]["url"];
+                                               $datarray['owner-avatar'] = $r[0]["photo"];
+
+                                               $datarray['author-name']   = $datarray['owner-name'];
+                                               $datarray['author-link']   = $datarray['owner-link'];
+                                               $datarray['author-avatar'] = $datarray['owner-avatar'];
+                                       }
+                               }
+
+                               $notify = true;
+                       } else
+                               $notify = false;
+
+                       $posted_id = item_store($datarray, false, $notify);
 
                        if(stristr($datarray['verb'],ACTIVITY_POKE)) {
                                $verb = urldecode(substr($datarray['verb'],strpos($datarray['verb'],'#')+1));
@@ -3594,16 +3716,16 @@ function local_delivery($importer,$data) {
 
                                        $links = parse_xml_string("<links>".unxmlify($xo->link)."</links>",false);
 
-                               foreach($links->link as $l) {
-                               $atts = $l->attributes();
-                               switch($atts['rel']) {
-                                       case "alternate":
+                               foreach($links->link as $l) {
+                               $atts = $l->attributes();
+                               switch($atts['rel']) {
+                                       case "alternate":
                                                                $Blink = $atts['href'];
                                                                break;
                                                        default:
                                                                break;
-                                   }
-                               }
+                                   }
+                               }
                                        if($Blink && link_compare($Blink,$a->get_baseurl() . '/profile/' . $importer['nickname'])) {
 
                                                // send a notification
@@ -3617,7 +3739,7 @@ function local_delivery($importer,$data) {
                                                        'to_email'     => $importer['email'],
                                                        'uid'          => $importer['importer_uid'],
                                                        'item'         => $datarray,
-                                                       'link'             => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $posted_id,
+                                                       'link'             => $a->get_baseurl().'/display/'.urlencode(get_item_guid($posted_id)),
                                                        'source_name'  => stripslashes($datarray['author-name']),
                                                        'source_link'  => $datarray['author-link'],
                                                        'source_photo' => ((link_compare($datarray['author-link'],$importer['url']))
@@ -3708,7 +3830,8 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
                                group_add_member($r[0]['uid'],'',$contact_record['id'],$r[0]['def_gid']);
                        }
 
-                       if(($r[0]['notify-flags'] & NOTIFY_INTRO) && ($r[0]['page-flags'] == PAGE_NORMAL)) {
+                       if(($r[0]['notify-flags'] & NOTIFY_INTRO) &&
+                               (($r[0]['page-flags'] == PAGE_NORMAL) OR ($r[0]['page-flags'] == PAGE_SOAPBOX))) {
                                $email_tpl = get_intltext_template('follow_notify_eml.tpl');
                                $email = replace_macros($email_tpl, array(
                                        '$requestor' => ((strlen($name)) ? $name : t('[Name Withheld]')),
@@ -4457,7 +4580,7 @@ function posted_dates($uid,$wall) {
                $start_month = datetime_convert('','',$dstart,'Y-m-d');
                $end_month = datetime_convert('','',$dend,'Y-m-d');
                $str = day_translate(datetime_convert('','',$dnow,'F Y'));
-               $ret[] = array($str,$end_month,$start_month);
+               $ret[] = array($str,$end_month,$start_month);
                $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d');
        }
        return $ret;