require_once('include/ostatus_conversation.php');
require_once('include/threads.php');
require_once('include/socgraph.php');
+require_once('mod/share.php');
-function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) {
+function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0, $forpubsub = false) {
$sitefeed = ((strlen($owner_nick)) ? false : true); // not yet implemented, need to rewrite huge chunks of following logic
$birthday = feed_birthday($owner_id,$owner['timezone']);
$sql_post_table = "";
+ $visibility = "";
if(! $public_feed) {
else
$sort = 'ASC';
+ // Include answers to status.net posts in public feeds
+ if($forpubsub) {
+ $sql_post_table = "INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent` ";
+ $visibility = "OR (`item`.`network` = 'dfrn' AND `thread`.`network`='stat')";
+ $date_field = "`received`";
+ $sql_order = "`item`.`received` DESC";
+ } else {
+ $date_field = "`changed`";
+ $sql_order = "`item`.`parent` ".$sort.", `item`.`created` ASC";
+ }
+
if(! strlen($last_update))
$last_update = 'now -30 days';
// AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )
// dbesc($check_date),
- $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
+ $r = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`,
`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`parent` != 0
- AND `item`.`wall` = 1 AND `item`.`changed` > '%s'
+ AND ((`item`.`wall` = 1) $visibility) AND `item`.$date_field > '%s'
$sql_extra
- ORDER BY `parent` %s, `created` ASC LIMIT 0, 300",
+ ORDER BY $sql_order LIMIT 0, 300",
intval($owner_id),
dbesc($check_date),
dbesc($sort)
// look for a photo. We should check media size and find the best one,
// but for now let's just find any author photo
+ // Additionally we look for an alternate author link. On OStatus this one is the one we want.
+
+ // Search for ostatus conversation url
+ $authorlinks = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"]["http://www.w3.org/2005/Atom"]["link"];
+ if (is_array($authorlinks)) {
+ foreach ($authorlinks as $link) {
+ $linkdata = array_shift($link["attribs"]);
+
+ if ($linkdata["rel"] == "alternate")
+ $res["author-link"] = $linkdata["href"];
+ };
+ }
$rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author');
if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
$base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
foreach($base as $link) {
+ if($link['attribs']['']['rel'] === 'alternate')
+ $res['author-link'] = unxmlify($link['attribs']['']['href']);
+
if(!x($res, 'author-avatar') || !$res['author-avatar']) {
if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
$res['author-avatar'] = unxmlify($link['attribs']['']['href']);
logger('get_atom_elements: Looking for status.net repeated message');
$message = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["content"][0]["data"];
- $orig_uri = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["id"][0]["data"];
+ $orig_id = ostatus_convert_href($child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["id"][0]["data"]);
$author = $child[SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10];
$uri = $author["uri"][0]["data"];
$name = $author["name"][0]["data"];
$avatar = $avatar["href"];
if (($name != "") and ($uri != "") and ($avatar != "") and ($message != "")) {
- logger('get_atom_elements: fixing sender of repeated message.');
+ logger('get_atom_elements: fixing sender of repeated message. '.$orig_id, LOGGER_DEBUG);
if (!intval(get_config('system','wall-to-wall_share'))) {
- $prefix = "[share author='".str_replace("'", "'",$name).
- "' profile='".$uri.
- "' avatar='".$avatar.
- "' link='".$orig_uri."']";
+ $prefix = share_header($name, $uri, $avatar, "", "", $orig_link);
$res["body"] = $prefix.html2bbcode($message)."[/share]";
} else {
$conversation = array_shift($link["attribs"]);
if ($conversation["rel"] == "ostatus:conversation") {
- $res["ostatus_conversation"] = $conversation["href"];
+ $res["ostatus_conversation"] = ostatus_convert_href($conversation["href"]);
logger('get_atom_elements: found conversation url '.$res["ostatus_conversation"]);
+ } elseif ($conversation["rel"] == "alternate") {
+ $res["plink"] = $conversation["href"];
+ logger('get_atom_elements: found plink '.$res["plink"]);
}
};
}
unset($arr['dsprsig']);
}
+ // Converting the plink
+ if ($arr['network'] == NETWORK_OSTATUS) {
+ if (isset($arr['plink']))
+ $arr['plink'] = ostatus_convert_href($arr['plink']);
+ elseif (isset($arr['uri']))
+ $arr['plink'] = ostatus_convert_href($arr['uri']);
+ }
+
// if an OStatus conversation url was passed in, it is stored and then
// removed from the array.
$ostatus_conversation = null;
/* check for create date and expire time */
$uid = intval($arr['uid']);
- $r = q("SELECT expire FROM user WHERE uid = %d", $uid);
+ $r = q("SELECT expire FROM user WHERE uid = %d", intval($uid));
if(count($r)) {
$expire_interval = $r[0]['expire'];
if ($expire_interval>0) {
}
}
+ // If there is no guid then take the same guid that was taken before for the same plink
+ if ((trim($arr['guid']) == "") AND (trim($arr['plink']) != "")) {
+ logger('item_store: checking for an existing guid for plink '.$arr['plink'], LOGGER_DEBUG);
+ $r = q("SELECT `guid` FROM `item` WHERE `plink` = '%s' AND `guid` != '' LIMIT 1",
+ dbesc(trim($arr['plink']))
+ );
+
+ if(count($r)) {
+ $arr['guid'] = $r[0]["guid"];
+ logger('item_store: found guid '.$arr['guid'].' for plink '.$arr['plink'], 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))
$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());
$arr['edited'] = ((x($arr,'edited') !== false) ? datetime_convert('UTC','UTC',$arr['edited']) : datetime_convert());
- $arr['commented'] = datetime_convert();
- $arr['received'] = datetime_convert();
- $arr['changed'] = datetime_convert();
+ $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['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : '');
$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(30));
$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 );
logger("item_store: Set network to ".$arr["network"]." for ".$arr["uri"], LOGGER_DEBUG);
}
+ if ($arr['guid'] != "") {
+ // Checking if there is already an item with the same guid
+ logger('checking for an item for user '.$arr['uid'].' on network '.$arr['network'].' with the guid '.$arr['guid'], LOGGER_DEBUG);
+ $r = q("SELECT `guid` FROM `item` WHERE `guid` = '%s' AND `network` = '%s' AND `uid` = '%d' LIMIT 1",
+ dbesc($arr['guid']), dbesc($arr['network']), intval($arr['uid']));
+
+ if(count($r)) {
+ logger('found item with guid '.$arr['guid'].' for user '.$arr['uid'].' on network '.$arr['network'], LOGGER_DEBUG);
+ return 0;
+ }
+ }
+
+ // Check for hashtags in the body and repair or add hashtag links
+ item_body_set_hashtags($arr);
+
$arr['thr-parent'] = $arr['parent-uri'];
if($arr['parent-uri'] === $arr['uri']) {
$parent_id = 0;
}
}
- $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1",
dbesc($arr['uri']),
+ dbesc($arr['network']),
intval($arr['uid'])
);
if($r && count($r)) {
- logger('item-store: duplicate item ignored. ' . print_r($arr,true));
+ logger('duplicated item with the same uri found. ' . print_r($arr,true));
return 0;
}
+ $r = q("SELECT `id` FROM `item` WHERE `plink` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($arr['plink']),
+ dbesc($arr['network']),
+ intval($arr['uid'])
+ );
+ if($r && count($r)) {
+ logger('duplicated item with the same plink found. ' . print_r($arr,true));
+ return 0;
+ }
+
+ // Check for an existing post with the same content. There seems to be a problem with OStatus.
+ $r = q("SELECT `id` FROM `item` WHERE `body` = '%s' AND `network` = '%s' AND `created` = '%s' AND `contact-id` = %d AND `uid` = %d LIMIT 1",
+ dbesc($arr['body']),
+ dbesc($arr['network']),
+ dbesc($arr['created']),
+ intval($arr['contact-id']),
+ intval($arr['uid'])
+ );
+ if($r && count($r)) {
+ logger('duplicated item with the same body found. ' . print_r($arr,true));
+ return 0;
+ }
+
+ // Is this item available in the global items (with uid=0)?
+ if ($arr["uid"] == 0) {
+ $arr["global"] = true;
+
+ q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($arr["guid"]));
+ } else {
+ $isglobal = q("SELECT `global` FROM `item` WHERE `uid` = 0 AND `guid` = '%s'", dbesc($arr["guid"]));
+
+ $arr["global"] = (count($isglobal) > 0);
+ }
+
+ // Fill the cache field
+ put_item_in_cache($arr);
+
call_hooks('post_remote',$arr);
if(x($arr,'cancel')) {
$current_post = $r[0]['id'];
logger('item_store: created item ' . $current_post);
- // Add every contact to the global contact table
- // Contacts from the statusnet connector are also added since you could add them in OStatus as well.
- if (!$arr['private'] AND in_array($arr["network"],
- array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_STATUSNET, ""))) {
- poco_check($arr["author-link"], $arr["author-name"], $arr["network"], $arr["author-avatar"], "", "", "", "", "", $arr["received"], $arr["contact-id"], $arr["uid"]);
-
- // Maybe its a body with a shared item? Then extract a global contact from it.
- poco_contact_from_body($arr["body"], $arr["received"], $arr["contact-id"], $arr["uid"]);
- }
-
- // Set "success_update" to the date of the last time we heard from this contact
- // This can be used to filter for inactive contacts and poco.
+ // Set "success_update" and "last-item" to the date of the last time we heard from this contact
+ // This can be used to filter for inactive contacts.
// Only do this for public postings to avoid privacy problems, since poco data is public.
// Don't set this value if it isn't from the owner (could be an author that we don't know)
- if (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"])))
- q("UPDATE `contact` SET `success_update` = '%s' WHERE `id` = %d",
- dbesc($arr['received']),
- intval($arr['contact-id'])
- );
-
- // Only check for notifications on start posts
- if ($arr['parent-uri'] === $arr['uri']) {
- add_thread($r[0]['id']);
- logger('item_store: Check notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
-
- // Send a notification for every new post?
- $r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1",
- intval($arr['contact-id']),
- intval($arr['uid'])
- );
-
- 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']));
- $item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d",
- intval($current_post),
- intval($arr['uid'])
- );
-
- $a = get_app();
+ $update = (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"])));
- require_once('include/enotify.php');
- notification(array(
- 'type' => NOTIFY_SHARE,
- 'notify_flags' => $u[0]['notify-flags'],
- 'language' => $u[0]['language'],
- 'to_name' => $u[0]['username'],
- 'to_email' => $u[0]['email'],
- 'uid' => $u[0]['uid'],
- 'item' => $item[0],
- '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'],
- 'verb' => ACTIVITY_TAG,
- 'otype' => 'item'
- ));
- logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
- }
+ // Is it a forum? Then we don't care about the rules from above
+ if (!$update AND ($arr["network"] == NETWORK_DFRN) AND ($arr["parent-uri"] === $arr["uri"])) {
+ $isforum = q("SELECT `forum` FROM `contact` WHERE `id` = %d AND `forum`",
+ intval($arr['contact-id']));
+ if ($isforum)
+ $update = true;
}
+ if ($update)
+ q("UPDATE `contact` SET `success_update` = '%s', `last-item` = '%s' WHERE `id` = %d",
+ dbesc($arr['received']),
+ dbesc($arr['received']),
+ intval($arr['contact-id'])
+ );
} else {
logger('item_store: could not locate created item');
return 0;
}
if(count($r) > 1) {
- logger('item_store: duplicated post occurred. Removing duplicates.');
+ 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']),
$arr['deleted'] = $parent_deleted;
// update the commented timestamp on the parent
-
- q("UPDATE `item` set `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- intval($parent_id)
- );
- update_thread($parent_id);
+ // Only update "commented" if it is really a comment
+ if (($arr['verb'] == ACTIVITY_POST) OR !get_config("system", "like_no_comment"))
+ q("UPDATE `item` SET `commented` = '%s', `changed` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ intval($parent_id)
+ );
+ else
+ q("UPDATE `item` SET `changed` = '%s' WHERE `id` = %d",
+ dbesc(datetime_convert()),
+ intval($parent_id)
+ );
if($dsprsig) {
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
$deleted = tag_deliver($arr['uid'],$current_post);
- // current post can be deleted if is for a communuty page and no mention are
+ // current post can be deleted if is for a community page and no mention are
// in it.
if (!$deleted AND !$dontcache) {
- // Store the fresh generated item into the cache
- $cachefile = get_cachefile(urlencode($arr["guid"])."-".hash("md5", $arr['body']));
-
- if (($cachefile != '') AND !file_exists($cachefile)) {
- $s = prepare_text($arr['body']);
- $a = get_app();
- $stamp1 = microtime(true);
- file_put_contents($cachefile, $s);
- $a->save_timestamp($stamp1, "file");
- logger('item_store: put item '.$current_post.' into cachefile '.$cachefile);
- }
-
$r = q('SELECT * FROM `item` WHERE id = %d', intval($current_post));
if (count($r) == 1) {
call_hooks('post_remote_end', $r[0]);
- } else {
+ } else
logger('item_store: new item not found in DB, id ' . $current_post);
- }
}
- create_tags_from_item($current_post, $dontcache);
+ // Add every contact of the post to the global contact table
+ poco_store($arr);
+
+ create_tags_from_item($current_post);
create_files_from_item($current_post);
+ // Only check for notifications on start posts
+ if ($arr['parent-uri'] === $arr['uri']) {
+ add_thread($current_post);
+ logger('item_store: Check notification for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
+
+ // Send a notification for every new post?
+ $r = q("SELECT `notify_new_posts` FROM `contact` WHERE `id` = %d AND `uid` = %d AND `notify_new_posts` LIMIT 1",
+ intval($arr['contact-id']),
+ intval($arr['uid'])
+ );
+ $send_notification = count($r);
+
+ if (!$send_notification) {
+ $tags = q("SELECT `url` FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` = %d AND `uid` = %d",
+ intval(TERM_OBJ_POST), intval($current_post), intval(TERM_MENTION), intval($arr['uid']));
+
+ if (count($tags)) {
+ foreach ($tags AS $tag) {
+ $r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `notify_new_posts`",
+ normalise_link($tag["url"]), intval($arr['uid']));
+ if (count($r))
+ $send_notification = true;
+ }
+ }
+ }
+
+ if ($send_notification) {
+ 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']));
+
+ $item = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d",
+ intval($current_post),
+ intval($arr['uid'])
+ );
+
+ $a = get_app();
+
+ require_once('include/enotify.php');
+ notification(array(
+ 'type' => NOTIFY_SHARE,
+ 'notify_flags' => $u[0]['notify-flags'],
+ 'language' => $u[0]['language'],
+ 'to_name' => $u[0]['username'],
+ 'to_email' => $u[0]['email'],
+ 'uid' => $u[0]['uid'],
+ 'item' => $item[0],
+ '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'],
+ 'verb' => ACTIVITY_TAG,
+ 'otype' => 'item',
+ 'parent' => $arr['parent']
+ ));
+ logger('item_store: Notification sent for contact '.$arr['contact-id'].' and post '.$current_post, LOGGER_DEBUG);
+ }
+ } else {
+ update_thread($parent_id);
+ add_shadow_entry($arr);
+ }
+
if ($notify)
proc_run('php', "include/notifier.php", $notify_type, $current_post);
return $current_post;
}
+function item_body_set_hashtags(&$item) {
+
+ $tags = get_tags($item["body"]);
+
+ // No hashtags?
+ if(!count($tags))
+ return(false);
+
+ // This sorting is important when there are hashtags that are part of other hashtags
+ // Otherwise there could be problems with hashtags like #test and #test2
+ rsort($tags);
+
+ $a = get_app();
+
+ $URLSearchString = "^\[\]";
+
+ // All hashtags should point to the home server
+ //$item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
+ // "#[url=".$a->get_baseurl()."/search?tag=$2]$2[/url]", $item["body"]);
+
+ //$item["tag"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
+ // "#[url=".$a->get_baseurl()."/search?tag=$2]$2[/url]", $item["tag"]);
+
+ // mask hashtags inside of url, bookmarks and attachments to avoid urls in urls
+ $item["body"] = preg_replace_callback("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
+ function ($match){
+ return("[url=".$match[1]."]".str_replace("#", "#", $match[2])."[/url]");
+ },$item["body"]);
+
+ $item["body"] = preg_replace_callback("/\[bookmark\=([$URLSearchString]*)\](.*?)\[\/bookmark\]/ism",
+ function ($match){
+ return("[bookmark=".$match[1]."]".str_replace("#", "#", $match[2])."[/bookmark]");
+ },$item["body"]);
+
+ $item["body"] = preg_replace_callback("/\[attachment (.*)\](.*?)\[\/attachment\]/ism",
+ function ($match){
+ return("[attachment ".str_replace("#", "#", $match[1])."]".$match[2]."[/attachment]");
+ },$item["body"]);
+
+ // Repair recursive urls
+ $item["body"] = preg_replace("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
+ "#$2", $item["body"]);
+
+ foreach($tags as $tag) {
+ if(strpos($tag,'#') !== 0)
+ continue;
+
+ if(strpos($tag,'[url='))
+ continue;
+
+ $basetag = str_replace('_',' ',substr($tag,1));
+
+ $newtag = '#[url='.$a->get_baseurl().'/search?tag='.rawurlencode($basetag).']'.$basetag.'[/url]';
+
+ $item["body"] = str_replace($tag, $newtag, $item["body"]);
+
+ if(!stristr($item["tag"],"/search?tag=".$basetag."]".$basetag."[/url]")) {
+ if(strlen($item["tag"]))
+ $item["tag"] = ','.$item["tag"];
+ $item["tag"] = $newtag.$item["tag"];
+ }
+ }
+
+ // Convert back the masked hashtags
+ $item["body"] = str_replace("#", "#", $item["body"]);
+}
+
function get_item_guid($id) {
$r = q("SELECT `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($id));
if (count($r))
return;
}
+ // Test - remove before flight
+// if ($contact['network'] === NETWORK_OSTATUS) {
+// $tempfile = tempnam(get_temppath(), "ostatus");
+// file_put_contents($tempfile, $xml);
+// }
+
$feed = new SimplePie();
$feed->set_raw_data($xml);
if($datedir)
$photo_timestamp = '';
$photo_url = '';
$birthday = '';
+ $contact_updated = '';
$hubs = $feed->get_links('hub');
logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA);
if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
$name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
$new_name = $elems['name'][0]['data'];
+
+ // Manually checking for changed contact names
+ if (($new_name != $contact['name']) AND ($new_name != "") AND ($name_updated <= $contact['name-date'])) {
+ $name_updated = date("c");
+ $photo_timestamp = date("c");
+ }
}
if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
- $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
+ if ($photo_timestamp == "")
+ $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
$photo_url = $elems['link'][0]['attribs']['']['href'];
}
if((is_array($contact)) && ($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $contact['avatar-date'])) {
logger('consume_feed: Updating photo for '.$contact['name'].' from '.$photo_url.' uid: '.$contact['uid']);
+
+ $contact_updated = $photo_timestamp;
+
require_once("include/Photo.php");
$photo_failure = false;
$have_photo = false;
}
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",
intval($contact['uid']),
intval($contact['id'])
}
}
+ if ($contact_updated AND $new_name AND $photo_url)
+ poco_check($contact['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $contact['id'], $contact['uid']);
+
if(strlen($birthday)) {
if(substr($birthday,0,4) != $contact['bdyear']) {
logger('consume_feed: updating birthday: ' . $birthday);
$contact['bdyear'] = substr($birthday,0,4);
}
-
}
$community_page = 0;
$new_name = '';
$photo_timestamp = '';
$photo_url = '';
+ $contact_updated = '';
$rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'owner');
if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
$name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
$new_name = $elems['name'][0]['data'];
+
+ // Manually checking for changed contact names
+ if (($new_name != $importer['name']) AND ($new_name != "") AND ($name_updated <= $importer['name-date'])) {
+ $name_updated = date("c");
+ $photo_timestamp = date("c");
+ }
}
if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
- $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
+ if ($photo_timestamp == "")
+ $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
$photo_url = $elems['link'][0]['attribs']['']['href'];
}
}
if(($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $importer['avatar-date'])) {
+
+ $contact_updated = $photo_timestamp;
+
logger('local_delivery: Updating photo for ' . $importer['name']);
require_once("include/Photo.php");
$photo_failure = false;
}
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",
intval($importer['importer_uid']),
intval($importer['id'])
}
}
-
+ if ($contact_updated AND $new_name AND $photo_url)
+ poco_check($importer['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $importer['id'], $importer['importer_uid']);
// Currently unsupported - needs a lot of work
$reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' );
$parent = 0;
if($posted_id) {
+
+ $datarray["id"] = $posted_id;
+
$r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($posted_id),
intval($importer['importer_uid'])
'verb' => $datarray['verb'],
'otype' => 'person',
'activity' => $verb,
-
+ 'parent' => $datarray['parent']
));
}
}
}
if(($r[0]['notify-flags'] & NOTIFY_INTRO) &&
- (($r[0]['page-flags'] == PAGE_NORMAL) OR ($r[0]['page-flags'] == PAGE_SOAPBOX))) {
-
-
+ in_array($r[0]['page-flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) {
notification(array(
'type' => NOTIFY_INTRO,
'otype' => 'intro'
));
-
}
}
}
// ignore the result
}
+ // If item has attachments, drop them
+
+ foreach(explode(",",$item['attach']) as $attach){
+ preg_match("|attach/(\d+)|", $attach, $matches);
+ q("DELETE FROM `attach` WHERE `id` = %d AND `uid` = %d",
+ intval($matches[1]),
+ local_user()
+ );
+ // ignore the result
+ }
+
+
// clean up item_id and sign meta-data tables
/*
dbesc($item['parent-uri']),
intval($item['uid'])
);
- create_tags_from_item($item['parent-uri'], $item['uid']);
- create_files_from_item($item['parent-uri'], $item['uid']);
+ create_tags_from_itemuri($item['parent-uri'], $item['uid']);
+ create_files_from_itemuri($item['parent-uri'], $item['uid']);
delete_thread_uri($item['parent-uri'], $item['uid']);
// ignore the result
}
// Add a relayable_retraction signature for Diaspora.
store_diaspora_retract_sig($item, $a->user, $a->get_baseurl());
}
+
$drop_id = intval($item['id']);
// send the notification upstream/downstream as the case may be
return false;
}
+/* modified posted_dates() {below} to arrange the list in years */
+function list_post_dates($uid, $wall) {
+ $dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d');
+
+ $dthen = first_post_date($uid, $wall);
+ if(! $dthen)
+ return array();
+
+ // Set the start and end date to the beginning of the month
+ $dnow = substr($dnow,0,8).'01';
+ $dthen = substr($dthen,0,8).'01';
+
+ $ret = array();
+
+ // Starting with the current month, get the first and last days of every
+ // month down to and including the month of the first post
+ while(substr($dnow, 0, 7) >= substr($dthen, 0, 7)) {
+ $dyear = intval(substr($dnow,0,4));
+ $dstart = substr($dnow,0,8) . '01';
+ $dend = substr($dnow,0,8) . get_dim(intval($dnow),intval(substr($dnow,5)));
+ $start_month = datetime_convert('','',$dstart,'Y-m-d');
+ $end_month = datetime_convert('','',$dend,'Y-m-d');
+ $str = day_translate(datetime_convert('','',$dnow,'F'));
+ if(! $ret[$dyear])
+ $ret[$dyear] = array();
+ $ret[$dyear][] = array($str,$end_month,$start_month);
+ $dnow = datetime_convert('','',$dnow . ' -1 month', 'Y-m-d');
+ }
+ return $ret;
+}
+
function posted_dates($uid,$wall) {
$dnow = datetime_convert('',date_default_timezone_get(),'now','Y-m-d');
/* if($wall && intval(get_pconfig($uid,'system','no_wall_archive_widget')))
return $o;*/
-
- $ret = posted_dates($uid,$wall);
+
+ $visible_years = get_pconfig($uid,'system','archive_visible_years');
+ if(! $visible_years)
+ $visible_years = 5;
+
+ $ret = list_post_dates($uid,$wall);
+
if(! count($ret))
return $o;
+ $cutoff_year = intval(datetime_convert('',date_default_timezone_get(),'now','Y')) - $visible_years;
+ $cutoff = ((array_key_exists($cutoff_year,$ret))? true : false);
+
$o = replace_macros(get_markup_template('posted_date_widget.tpl'),array(
'$title' => t('Archives'),
- '$size' => ((count($ret) > 6) ? 6 : count($ret)),
+ '$size' => $visible_years,
+ '$cutoff_year' => $cutoff_year,
+ '$cutoff' => $cutoff,
'$url' => $url,
- '$dates' => $ret
+ '$dates' => $ret,
+ '$showmore' => t('show more')
+
));
return $o;
}