Merge pull request #2286 from annando/1601-dfrn

Complete rewrite of DFRN generation
This commit is contained in:
fabrixxm 2016-01-27 09:42:03 +01:00
commit f18679053b
20 changed files with 1142 additions and 1182 deletions

View File

@ -530,6 +530,8 @@ class App {
private $cached_profile_image; private $cached_profile_image;
private $cached_profile_picdate; private $cached_profile_picdate;
private static $a;
/** /**
* @brief App constructor. * @brief App constructor.
*/ */
@ -710,6 +712,8 @@ class App {
} }
} }
self::$a = $this;
} }
function get_basepath() { function get_basepath() {
@ -734,6 +738,10 @@ class App {
function get_baseurl($ssl = false) { function get_baseurl($ssl = false) {
// Is the function called statically?
if (!is_object($this))
return(self::$a->get_baseurl($ssl));
$scheme = $this->scheme; $scheme = $this->scheme;
if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) { if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) {

View File

@ -132,8 +132,8 @@ function terminate_friendship($user,$self,$contact) {
diaspora_unshare($user,$contact); diaspora_unshare($user,$contact);
} }
elseif($contact['network'] === NETWORK_DFRN) { elseif($contact['network'] === NETWORK_DFRN) {
require_once('include/items.php'); require_once('include/dfrn.php');
dfrn_deliver($user,$contact,'placeholder', 1); dfrn::deliver($user,$contact,'placeholder', 1);
} }
} }
@ -208,15 +208,15 @@ function get_contact_details_by_url($url, $uid = -1) {
} }
// Fetching further contact data from the contact table // Fetching further contact data from the contact table
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` = '%s'", $r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd`, `self` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` IN ('%s', '')",
dbesc(normalise_link($url)), intval($uid), dbesc($profile["network"])); dbesc(normalise_link($url)), intval($uid), dbesc($profile["network"]));
if (!count($r) AND !isset($profile)) if (!count($r) AND !isset($profile))
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d", $r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd`, `self` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($url)), intval($uid)); dbesc(normalise_link($url)), intval($uid));
if (!count($r) AND !isset($profile)) if (!count($r) AND !isset($profile))
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0", $r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
dbesc(normalise_link($url))); dbesc(normalise_link($url)));
if ($r) { if ($r) {
@ -228,7 +228,7 @@ function get_contact_details_by_url($url, $uid = -1) {
$profile["nick"] = $r[0]["nick"]; $profile["nick"] = $r[0]["nick"];
if (!isset($profile["addr"]) AND $r[0]["addr"]) if (!isset($profile["addr"]) AND $r[0]["addr"])
$profile["addr"] = $r[0]["addr"]; $profile["addr"] = $r[0]["addr"];
if (!isset($profile["photo"]) AND $r[0]["photo"]) if ((!isset($profile["photo"]) OR $r[0]["self"]) AND $r[0]["photo"])
$profile["photo"] = $r[0]["photo"]; $profile["photo"] = $r[0]["photo"];
if (!isset($profile["location"]) AND $r[0]["location"]) if (!isset($profile["location"]) AND $r[0]["location"])
$profile["location"] = $r[0]["location"]; $profile["location"] = $r[0]["location"];
@ -246,6 +246,8 @@ function get_contact_details_by_url($url, $uid = -1) {
$profile["addr"] = $r[0]["addr"]; $profile["addr"] = $r[0]["addr"];
if (!isset($profile["bd"]) AND $r[0]["bd"]) if (!isset($profile["bd"]) AND $r[0]["bd"])
$profile["bd"] = $r[0]["bd"]; $profile["bd"] = $r[0]["bd"];
if (isset($r[0]["thumb"]))
$profile["thumb"] = $r[0]["thumb"];
if ($r[0]["uid"] == 0) if ($r[0]["uid"] == 0)
$profile["cid"] = 0; $profile["cid"] = 0;
else else
@ -665,4 +667,34 @@ function posts_from_contact($a, $contact_id) {
return $o; return $o;
} }
/**
* @brief Returns a formatted location string from the given profile array
*
* @param array $profile Profile array (Generated from the "profile" table)
*
* @return string Location string
*/
function formatted_location($profile) {
$location = '';
if($profile['locality'])
$location .= $profile['locality'];
if($profile['region'] AND ($profile['locality'] != $profile['region'])) {
if($location)
$location .= ', ';
$location .= $profile['region'];
}
if($profile['country-name']) {
if($location)
$location .= ', ';
$location .= $profile['country-name'];
}
return $location;
}
?> ?>

View File

@ -30,7 +30,6 @@ function cron_run(&$argv, &$argc){
require_once('include/session.php'); require_once('include/session.php');
require_once('include/datetime.php'); require_once('include/datetime.php');
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php'); require_once('include/items.php');
require_once('include/Contact.php'); require_once('include/Contact.php');
require_once('include/email.php'); require_once('include/email.php');

View File

@ -5,6 +5,7 @@ require_once('include/html2plain.php');
require_once("include/Scrape.php"); require_once("include/Scrape.php");
require_once('include/diaspora.php'); require_once('include/diaspora.php');
require_once("include/ostatus.php"); require_once("include/ostatus.php");
require_once("include/dfrn.php");
function delivery_run(&$argv, &$argc){ function delivery_run(&$argv, &$argc){
global $a, $db; global $a, $db;
@ -264,8 +265,6 @@ function delivery_run(&$argv, &$argc){
if(count($r)) if(count($r))
$contact = $r[0]; $contact = $r[0];
$hubxml = feed_hublinks();
if($contact['self']) if($contact['self'])
continue; continue;
@ -278,138 +277,54 @@ function delivery_run(&$argv, &$argc){
case NETWORK_DFRN: case NETWORK_DFRN:
logger('notifier: '.$target_item["guid"].' dfrndelivery: ' . $contact['name']); logger('notifier: '.$target_item["guid"].' dfrndelivery: ' . $contact['name']);
$feed_template = get_markup_template('atom_feed.tpl'); if ($mail) {
$mail_template = get_markup_template('atom_mail.tpl'); $item['body'] = fix_private_photos($item['body'],$owner['uid'],null,$message[0]['contact-id']);
$atom = dfrn::mail($item, $owner);
$atom = ''; } elseif ($fsuggest) {
$atom = dfrn::fsuggest($item, $owner);
q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1", intval($item['id']));
$birthday = feed_birthday($owner['uid'],$owner['timezone']); } elseif ($relocate)
$atom = dfrn::relocate($owner, $uid);
if(strlen($birthday)) elseif($followup) {
$birthday = '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>'; $msgitems = array();
$atom .= replace_macros($feed_template, array(
'$version' => xmlify(FRIENDICA_VERSION),
'$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
'$hub' => $hubxml,
'$salmon' => '', // private feed, we don't use salmon here
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
'$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
'$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
'$birthday' => $birthday,
'$community' => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
));
if($mail) {
$public_message = false; // mail is not public
$body = fix_private_photos($item['body'],$owner['uid'],null,$message[0]['contact-id']);
$atom .= replace_macros($mail_template, array(
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$thumb' => xmlify($owner['thumb']),
'$item_id' => xmlify($item['uri']),
'$subject' => xmlify($item['title']),
'$created' => xmlify(datetime_convert('UTC', 'UTC', $item['created'] . '+00:00' , ATOM_TIME)),
'$content' => xmlify($body),
'$parent_id' => xmlify($item['parent-uri'])
));
} elseif($fsuggest) {
$public_message = false; // suggestions are not public
$sugg_template = get_markup_template('atom_suggest.tpl');
$atom .= replace_macros($sugg_template, array(
'$name' => xmlify($item['name']),
'$url' => xmlify($item['url']),
'$photo' => xmlify($item['photo']),
'$request' => xmlify($item['request']),
'$note' => xmlify($item['note'])
));
// We don't need this any more
q("DELETE FROM `fsuggest` WHERE `id` = %d LIMIT 1",
intval($item['id'])
);
} elseif($relocate) {
$public_message = false; // suggestions are not public
$sugg_template = get_markup_template('atom_relocate.tpl');
/* get site pubkey. this could be a new installation with no site keys*/
$pubkey = get_config('system','site_pubkey');
if(! $pubkey) {
$res = new_keypair(1024);
set_config('system','site_prvkey', $res['prvkey']);
set_config('system','site_pubkey', $res['pubkey']);
}
$rp = q("SELECT `resource-id` , `scale`, type FROM `photo`
WHERE `profile` = 1 AND `uid` = %d ORDER BY scale;", $uid);
$photos = array();
$ext = Photo::supportedTypes();
foreach($rp as $p){
$photos[$p['scale']] = $a->get_baseurl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']];
}
unset($rp, $ext);
$atom .= replace_macros($sugg_template, array(
'$name' => xmlify($owner['name']),
'$photo' => xmlify($photos[4]),
'$thumb' => xmlify($photos[5]),
'$micro' => xmlify($photos[6]),
'$url' => xmlify($owner['url']),
'$request' => xmlify($owner['request']),
'$confirm' => xmlify($owner['confirm']),
'$notify' => xmlify($owner['notify']),
'$poll' => xmlify($owner['poll']),
'$sitepubkey' => xmlify(get_config('system','site_pubkey')),
//'$pubkey' => xmlify($owner['pubkey']),
//'$prvkey' => xmlify($owner['prvkey']),
));
unset($photos);
} elseif($followup) {
foreach($items as $item) { // there is only one item foreach($items as $item) { // there is only one item
if(! $item['parent']) if(!$item['parent'])
continue; continue;
if($item['id'] == $item_id) { if($item['id'] == $item_id) {
logger('followup: item: ' . print_r($item,true), LOGGER_DATA); logger('followup: item: ' . print_r($item,true), LOGGER_DATA);
$atom .= atom_entry($item,'text',null,$owner,false); $msgitems[] = $item;
} }
} }
$atom = dfrn::entries($msgitems,$owner);
} else { } else {
$msgitems = array();
foreach($items as $item) { foreach($items as $item) {
if(! $item['parent']) if(!$item['parent'])
continue; continue;
// private emails may be in included in public conversations. Filter them. // private emails may be in included in public conversations. Filter them.
if(($public_message) && $item['private'] == 1) if(($public_message) && $item['private'])
continue; continue;
$item_contact = get_item_contact($item,$icontacts); $item_contact = get_item_contact($item,$icontacts);
if(! $item_contact) if(!$item_contact)
continue; continue;
if($normal_mode) { if($normal_mode) {
if($item_id == $item['id'] || $item['id'] == $item['parent']) if($item_id == $item['id'] || $item['id'] == $item['parent']) {
$atom .= atom_entry($item,'text',null,$owner,true,(($top_level) ? $contact['id'] : 0)); $item["entry:comment-allow"] = true;
} else $item["entry:cid"] = (($top_level) ? $contact['id'] : 0);
$atom .= atom_entry($item,'text',null,$owner,true); $msgitems[] = $item;
}
} else {
$item["entry:comment-allow"] = true;
$msgitems[] = $item;
} }
} }
$atom = dfrn::entries($msgitems,$owner);
}
$atom .= '</feed>' . "\r\n"; logger('notifier entry: '.$contact["url"].' '.$target_item["guid"].' entry: '.$atom, LOGGER_DEBUG);
logger('notifier: '.$contact["url"].' '.$target_item["guid"].' entry: '.$atom, LOGGER_DEBUG);
logger('notifier: ' . $atom, LOGGER_DATA); logger('notifier: ' . $atom, LOGGER_DATA);
$basepath = implode('/', array_slice(explode('/',$contact['url']),0,3)); $basepath = implode('/', array_slice(explode('/',$contact['url']),0,3));
@ -458,7 +373,6 @@ function delivery_run(&$argv, &$argc){
if (($x[0]['page-flags'] == PAGE_SOAPBOX) AND $top_level) if (($x[0]['page-flags'] == PAGE_SOAPBOX) AND $top_level)
break; break;
require_once('library/simplepie/simplepie.inc');
logger('mod-delivery: local delivery'); logger('mod-delivery: local delivery');
local_delivery($x[0],$atom); local_delivery($x[0],$atom);
break; break;
@ -466,7 +380,7 @@ function delivery_run(&$argv, &$argc){
} }
if(! was_recently_delayed($contact['id'])) if(! was_recently_delayed($contact['id']))
$deliver_status = dfrn_deliver($owner,$contact,$atom); $deliver_status = dfrn::deliver($owner,$contact,$atom);
else else
$deliver_status = (-1); $deliver_status = (-1);

1048
include/dfrn.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,6 @@ function expire_run(&$argv, &$argc){
require_once('include/session.php'); require_once('include/session.php');
require_once('include/datetime.php'); require_once('include/datetime.php');
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php'); require_once('include/items.php');
require_once('include/Contact.php'); require_once('include/Contact.php');

View File

@ -19,310 +19,12 @@ require_once('mod/share.php');
require_once('library/defuse/php-encryption-1.2.1/Crypto.php'); require_once('library/defuse/php-encryption-1.2.1/Crypto.php');
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
$public_feed = (($dfrn_id) ? false : true);
$starred = false; // not yet implemented, possible security issues
$converse = false;
if($public_feed && $a->argc > 2) {
for($x = 2; $x < $a->argc; $x++) {
if($a->argv[$x] == 'converse')
$converse = true;
if($a->argv[$x] == 'starred')
$starred = true;
if($a->argv[$x] === 'category' && $a->argc > ($x + 1) && strlen($a->argv[$x+1]))
$category = $a->argv[$x+1];
}
}
// default permissions - anonymous user
$sql_extra = " AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' ";
$r = q("SELECT `contact`.*, `user`.`uid` AS `user_uid`, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`self` = 1 AND `user`.`nickname` = '%s' LIMIT 1",
dbesc($owner_nick)
);
if(! count($r))
killme();
$owner = $r[0];
$owner_id = $owner['user_uid'];
$owner_nick = $owner['nickname'];
$birthday = feed_birthday($owner_id,$owner['timezone']);
$sql_post_table = "";
$visibility = "";
if(! $public_feed) {
$sql_extra = '';
switch($direction) {
case (-1):
$sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
$my_id = $dfrn_id;
break;
case 0:
$sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
$my_id = '1:' . $dfrn_id;
break;
case 1:
$sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
$my_id = '0:' . $dfrn_id;
break;
default:
return false;
break; // NOTREACHED
}
$r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `contact`.`uid` = %d $sql_extra LIMIT 1",
intval($owner_id)
);
if(! count($r))
killme();
$contact = $r[0];
require_once('include/security.php');
$groups = init_groups_visitor($contact['id']);
if(count($groups)) {
for($x = 0; $x < count($groups); $x ++)
$groups[$x] = '<' . intval($groups[$x]) . '>' ;
$gs = implode('|', $groups);
}
else
$gs = '<<>>' ; // Impossible to match
$sql_extra = sprintf("
AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' )
AND ( `deny_cid` = '' OR NOT `deny_cid` REGEXP '<%d>' )
AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )
AND ( `deny_gid` = '' OR NOT `deny_gid` REGEXP '%s')
",
intval($contact['id']),
intval($contact['id']),
dbesc($gs),
dbesc($gs)
);
}
if($public_feed)
$sort = 'DESC';
else
$sort = 'ASC';
// Include answers to status.net posts in pubsub feeds
if($forpubsub) {
$sql_post_table = "INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent`
LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`";
$visibility = sprintf("AND (`item`.`parent` = `item`.`id`) OR (`item`.`network` = '%s' AND ((`thread`.`network`='%s') OR (`thritem`.`network` = '%s')))",
dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS));
$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';
if(isset($category)) {
$sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
dbesc(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($owner_id));
//$sql_extra .= file_tag_file_query('item',$category,'category');
}
if($public_feed) {
if(! $converse)
$sql_extra .= " AND `contact`.`self` = 1 ";
}
$check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
// AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )
// dbesc($check_date),
$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`,
`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`,
`sign`.`signed_text`, `sign`.`signature`, `sign`.`signer`
FROM `item` $sql_post_table
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
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) $visibility) AND `item`.$date_field > '%s'
$sql_extra
ORDER BY $sql_order LIMIT 0, 300",
intval($owner_id),
dbesc($check_date),
dbesc($sort)
);
// Will check further below if this actually returned results.
// We will provide an empty feed if that is the case.
$items = $r;
$feed_template = get_markup_template(($dfrn_id) ? 'atom_feed_dfrn.tpl' : 'atom_feed.tpl');
$atom = '';
$hubxml = feed_hublinks();
$salmon = feed_salmonlinks($owner_nick);
$alternatelink = $owner['url'];
if(isset($category))
$alternatelink .= "/category/".$category;
$atom .= replace_macros($feed_template, array(
'$version' => xmlify(FRIENDICA_VERSION),
'$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner_nick),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now' , ATOM_TIME)) ,
'$hub' => $hubxml,
'$salmon' => $salmon,
'$alternatelink' => xmlify($alternatelink),
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
'$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
'$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
'$birthday' => ((strlen($birthday)) ? '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>' : ''),
'$community' => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
));
call_hooks('atom_feed', $atom);
if(! count($items)) {
call_hooks('atom_feed_end', $atom);
$atom .= '</feed>' . "\r\n";
return $atom;
}
foreach($items as $item) {
// prevent private email from leaking.
if($item['network'] === NETWORK_MAIL)
continue;
// public feeds get html, our own nodes use bbcode
if($public_feed) {
$type = 'html';
// catch any email that's in a public conversation and make sure it doesn't leak
if($item['private'])
continue;
}
else {
$type = 'text';
}
$atom .= atom_entry($item,$type,null,$owner,true);
}
call_hooks('atom_feed_end', $atom);
$atom .= '</feed>' . "\r\n";
return $atom;
}
function construct_verb($item) { function construct_verb($item) {
if($item['verb']) if($item['verb'])
return $item['verb']; return $item['verb'];
return ACTIVITY_POST; return ACTIVITY_POST;
} }
function construct_activity_object($item) {
if($item['object']) {
$o = '<as:object>' . "\r\n";
$r = parse_xml_string($item['object'],false);
if(! $r)
return '';
if($r->type)
$o .= '<as:object-type>' . xmlify($r->type) . '</as:object-type>' . "\r\n";
if($r->id)
$o .= '<id>' . xmlify($r->id) . '</id>' . "\r\n";
if($r->title)
$o .= '<title>' . xmlify($r->title) . '</title>' . "\r\n";
if($r->link) {
if(substr($r->link,0,1) === '<') {
// patch up some facebook "like" activity objects that got stored incorrectly
// for a couple of months prior to 9-Jun-2011 and generated bad XML.
// we can probably remove this hack here and in the following function in a few months time.
if(strstr($r->link,'&') && (! strstr($r->link,'&amp;')))
$r->link = str_replace('&','&amp;', $r->link);
$r->link = preg_replace('/\<link(.*?)\"\>/','<link$1"/>',$r->link);
$o .= $r->link;
}
else
$o .= '<link rel="alternate" type="text/html" href="' . xmlify($r->link) . '" />' . "\r\n";
}
if($r->content)
$o .= '<content type="html" >' . xmlify(bbcode($r->content)) . '</content>' . "\r\n";
$o .= '</as:object>' . "\r\n";
return $o;
}
return '';
}
function construct_activity_target($item) {
if($item['target']) {
$o = '<as:target>' . "\r\n";
$r = parse_xml_string($item['target'],false);
if(! $r)
return '';
if($r->type)
$o .= '<as:object-type>' . xmlify($r->type) . '</as:object-type>' . "\r\n";
if($r->id)
$o .= '<id>' . xmlify($r->id) . '</id>' . "\r\n";
if($r->title)
$o .= '<title>' . xmlify($r->title) . '</title>' . "\r\n";
if($r->link) {
if(substr($r->link,0,1) === '<') {
if(strstr($r->link,'&') && (! strstr($r->link,'&amp;')))
$r->link = str_replace('&','&amp;', $r->link);
$r->link = preg_replace('/\<link(.*?)\"\>/','<link$1"/>',$r->link);
$o .= $r->link;
}
else
$o .= '<link rel="alternate" type="text/html" href="' . xmlify($r->link) . '" />' . "\r\n";
}
if($r->content)
$o .= '<content type="html" >' . xmlify(bbcode($r->content)) . '</content>' . "\r\n";
$o .= '</as:target>' . "\r\n";
return $o;
}
return '';
}
/* limit_body_size() /* limit_body_size()
* *
* The purpose of this function is to apply system message length limits to * The purpose of this function is to apply system message length limits to
@ -441,8 +143,6 @@ function title_is_body($title, $body) {
return($title == $body); return($title == $body);
} }
function get_atom_elements($feed, $item, $contact = array()) { function get_atom_elements($feed, $item, $contact = array()) {
require_once('library/HTMLPurifier.auto.php'); require_once('library/HTMLPurifier.auto.php');
@ -466,17 +166,6 @@ function get_atom_elements($feed, $item, $contact = array()) {
$res['body'] = unxmlify($item->get_content()); $res['body'] = unxmlify($item->get_content());
$res['plink'] = unxmlify($item->get_link(0)); $res['plink'] = unxmlify($item->get_link(0));
if (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND strstr($res['plink'], ".app.net/")) {
logger("get_atom_elements: detected app.net posting: ".print_r($res, true), LOGGER_DEBUG);
$res['title'] = "";
$res['body'] = nl2br($res['body']);
}
// removing the content of the title if its identically to the body
// This helps with auto generated titles e.g. from tumblr
if (title_is_body($res["title"], $res["body"]))
$res['title'] = "";
if($res['plink']) if($res['plink'])
$base_url = implode('/', array_slice(explode('/',$res['plink']),0,3)); $base_url = implode('/', array_slice(explode('/',$res['plink']),0,3));
else else
@ -854,62 +543,6 @@ function get_atom_elements($feed, $item, $contact = array()) {
$res['target'] .= '</target>' . "\n"; $res['target'] .= '</target>' . "\n";
} }
// This is some experimental stuff. By now retweets are shown with "RT:"
// But: There is data so that the message could be shown similar to native retweets
// There is some better way to parse this array - but it didn't worked for me.
$child = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["entry"][0]["child"]["http://activitystrea.ms/spec/1.0/"][object][0]["child"];
if (is_array($child)) {
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_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 = @array_shift($author["link"][2]["attribs"]);
$avatar = $avatar["href"];
if (($name != "") and ($uri != "") and ($avatar != "") and ($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_header($name, $uri, $avatar, "", "", $orig_link);
$res["body"] = $prefix.html2bbcode($message)."[/share]";
} else {
$res["owner-name"] = $res["author-name"];
$res["owner-link"] = $res["author-link"];
$res["owner-avatar"] = $res["author-avatar"];
$res["author-name"] = $name;
$res["author-link"] = $uri;
$res["author-avatar"] = $avatar;
$res["body"] = html2bbcode($message);
}
}
}
if (isset($contact["network"]) AND ($contact["network"] == NETWORK_FEED) AND $contact['fetch_further_information']) {
$preview = "";
// Handle enclosures and treat them as preview picture
if (isset($attach))
foreach ($attach AS $attachment)
if ($attachment->type == "image/jpeg")
$preview = $attachment->link;
$res["body"] = $res["title"].add_page_info($res['plink'], false, $preview, ($contact['fetch_further_information'] == 2), $contact['ffi_keyword_blacklist']);
$res["tag"] = add_page_keywords($res['plink'], false, $preview, ($contact['fetch_further_information'] == 2), $contact['ffi_keyword_blacklist']);
$res["title"] = "";
$res["object-type"] = ACTIVITY_OBJ_BOOKMARK;
unset($res["attach"]);
} 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/")) {
$res["body"] = add_page_info_to_body($res["body"]);
}
$arr = array('feed' => $feed, 'item' => $item, 'result' => $res); $arr = array('feed' => $feed, 'item' => $item, 'result' => $res);
call_hooks('parse_atom', $arr); call_hooks('parse_atom', $arr);
@ -2063,245 +1696,9 @@ function tgroup_check($uid,$item) {
if((! $community_page) && (! $prvgroup)) if((! $community_page) && (! $prvgroup))
return false; return false;
return true; return true;
} }
function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
$a = get_app();
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
if($contact['duplex'] && $contact['dfrn-id'])
$idtosend = '0:' . $orig_id;
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 = '';
switch($ssl_val){
case SSL_POLICY_FULL:
$ssl_policy = 'full';
break;
case SSL_POLICY_SELFSIGN:
$ssl_policy = 'self';
break;
case SSL_POLICY_NONE:
default:
$ssl_policy = 'none';
break;
}
$url = $contact['notify'] . '&dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . (($rino) ? '&rino='.$rino : '');
logger('dfrn_deliver: ' . $url);
$xml = fetch_url($url);
$curl_stat = $a->get_curl_code();
if(! $curl_stat)
return(-1); // timed out
logger('dfrn_deliver: ' . $xml, LOGGER_DATA);
if(! $xml)
return 3;
if(strpos($xml,'<?xml') === false) {
logger('dfrn_deliver: no valid XML returned');
logger('dfrn_deliver: returned XML: ' . $xml, LOGGER_DATA);
return 3;
}
$res = parse_xml_string($xml);
if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
return (($res->status) ? $res->status : 3);
$postvars = array();
$sent_dfrn_id = hex2bin((string) $res->dfrn_id);
$challenge = hex2bin((string) $res->challenge);
$perm = (($res->perm) ? $res->perm : null);
$dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0);
$rino_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;
$final_dfrn_id = '';
if($perm) {
if((($perm == 'rw') && (! intval($contact['writable'])))
|| (($perm == 'r') && (intval($contact['writable'])))) {
q("update contact set writable = %d where id = %d",
intval(($perm == 'rw') ? 1 : 0),
intval($contact['id'])
);
$contact['writable'] = (string) 1 - intval($contact['writable']);
}
}
if(($contact['duplex'] && strlen($contact['pubkey']))
|| ($owner['page-flags'] == PAGE_COMMUNITY && strlen($contact['pubkey']))
|| ($contact['rel'] == CONTACT_IS_SHARING && strlen($contact['pubkey']))) {
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
}
else {
openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
}
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if(strpos($final_dfrn_id,':') == 1)
$final_dfrn_id = substr($final_dfrn_id,2);
if($final_dfrn_id != $orig_id) {
logger('dfrn_deliver: wrong dfrn_id.');
// did not decode properly - cannot trust this site
return 3;
}
$postvars['dfrn_id'] = $idtosend;
$postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
if($dissolve)
$postvars['dissolve'] = '1';
if((($contact['rel']) && ($contact['rel'] != CONTACT_IS_SHARING) && (! $contact['blocked'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
$postvars['data'] = $atom;
$postvars['perm'] = 'rw';
}
else {
$postvars['data'] = str_replace('<dfrn:comment-allow>1','<dfrn:comment-allow>0',$atom);
$postvars['perm'] = 'r';
}
$postvars['ssl_policy'] = $ssl_policy;
if($page)
$postvars['page'] = $page;
if($rino>0 && $rino_remote_version>0 && (! $dissolve)) {
logger('rino version: '. $rino_remote_version);
switch($rino_remote_version) {
case 1:
// Deprecated rino version!
$key = substr(random_string(),0,16);
$data = aes_encrypt($postvars['data'],$key);
break;
case 2:
// RINO 2 based on php-encryption
try {
$key = Crypto::createNewRandomKey();
} catch (CryptoTestFailed $ex) {
logger('Cannot safely create a key');
return -1;
} catch (CannotPerformOperation $ex) {
logger('Cannot safely create a key');
return -1;
}
try {
$data = Crypto::encrypt($postvars['data'], $key);
} catch (CryptoTestFailed $ex) {
logger('Cannot safely perform encryption');
return -1;
} catch (CannotPerformOperation $ex) {
logger('Cannot safely perform encryption');
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);
if($dfrn_version >= 2.1) {
if(($contact['duplex'] && strlen($contact['pubkey']))
|| ($owner['page-flags'] == PAGE_COMMUNITY && strlen($contact['pubkey']))
|| ($contact['rel'] == CONTACT_IS_SHARING && strlen($contact['pubkey']))) {
openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']);
}
else {
openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']);
}
}
else {
if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']);
}
else {
openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']);
}
}
logger('md5 rawkey ' . md5($postvars['key']));
$postvars['key'] = bin2hex($postvars['key']);
}
logger('dfrn_deliver: ' . "SENDING: " . print_r($postvars,true), LOGGER_DATA);
$xml = post_url($contact['notify'],$postvars);
logger('dfrn_deliver: ' . "RECEIVED: " . $xml, LOGGER_DATA);
$curl_stat = $a->get_curl_code();
if((! $curl_stat) || (! strlen($xml)))
return(-1); // timed out
if(($curl_stat == 503) && (stristr($a->get_curl_headers(),'retry-after')))
return(-1);
if(strpos($xml,'<?xml') === false) {
logger('dfrn_deliver: phase 2: no valid XML returned');
logger('dfrn_deliver: phase 2: returned XML: ' . $xml, LOGGER_DATA);
return 3;
}
if($contact['term-date'] != '0000-00-00 00:00:00') {
logger("dfrn_deliver: $url back from the dead - removing mark for death");
require_once('include/Contact.php');
unmark_for_death($contact);
}
$res = parse_xml_string($xml);
return $res->status;
}
/* /*
This function returns true if $update has an edited timestamp newer This function returns true if $update has an edited timestamp newer
than $existing, i.e. $update contains new data which should override than $existing, i.e. $update contains new data which should override
@ -3067,6 +2464,9 @@ function item_is_remote_self($contact, &$datarray) {
} }
function local_delivery($importer,$data) { function local_delivery($importer,$data) {
require_once('library/simplepie/simplepie.inc');
$a = get_app(); $a = get_app();
logger(__function__, LOGGER_TRACE); logger(__function__, LOGGER_TRACE);
@ -4340,7 +3740,6 @@ function lose_sharer($importer,$contact,$datarray,$item) {
} }
} }
function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') { function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') {
$a = get_app(); $a = get_app();
@ -4383,189 +3782,6 @@ function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') {
} }
function atom_author($tag,$name,$uri,$h,$w,$photo,$geo) {
$o = '';
if(! $tag)
return $o;
$name = xmlify($name);
$uri = xmlify($uri);
$h = intval($h);
$w = intval($w);
$photo = xmlify($photo);
$o .= "<$tag>\r\n";
$o .= "\t<name>$name</name>\r\n";
$o .= "\t<uri>$uri</uri>\r\n";
$o .= "\t".'<link rel="photo" type="image/jpeg" media:width="' . $w . '" media:height="' . $h . '" href="' . $photo . '" />' . "\r\n";
$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`
INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid`
INNER JOIN `user` ON `user`.`uid` = `profile`.`uid`
WHERE `profile`.`is-default` AND `contact`.`self` AND
NOT `user`.`hidewall` AND `contact`.`nurl`='%s'",
dbesc(normalise_link($uri)));
if ($r) {
$location = '';
if($r[0]['locality'])
$location .= $r[0]['locality'];
if($r[0]['region']) {
if($location)
$location .= ', ';
$location .= $r[0]['region'];
}
if($r[0]['country-name']) {
if($location)
$location .= ', ';
$location .= $r[0]['country-name'];
}
$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(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";
$o .= "\t<poco:urls>\r\n";
$o .= "\t<poco:type>homepage</poco:type>\r\n";
$o .= "\t\t<poco:value>".xmlify($r[0]["homepage"])."</poco:value>\r\n";
$o .= "\t\t<poco:primary>true</poco:primary>\r\n";
$o .= "\t</poco:urls>\r\n";
}
}
call_hooks('atom_author', $o);
$o .= "</$tag>\r\n";
return $o;
}
function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
$a = get_app();
if(! $item['parent'])
return;
if($item['deleted'])
return '<at:deleted-entry ref="' . xmlify($item['uri']) . '" when="' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '" />' . "\r\n";
if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
$body = fix_private_photos($item['body'],$owner['uid'],$item,$cid);
else
$body = $item['body'];
$o = "\r\n\r\n<entry>\r\n";
if(is_array($author))
$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']), $item['coord']);
if(strlen($item['owner-name']))
$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"]));
$parent_item = (($item['thr-parent']) ? $item['thr-parent'] : $item['parent-uri']);
$o .= '<thr:in-reply-to ref="'.xmlify($parent_item).'" type="text/html" href="'.xmlify($a->get_baseurl().'/display/'.$parent[0]['guid']).'" />'."\r\n";
}
$htmlbody = $body;
if ($item['title'] != "")
$htmlbody = "[b]".$item['title']."[/b]\n\n".$htmlbody;
$htmlbody = bbcode($htmlbody, false, false, 7);
$o .= '<id>' . xmlify($item['uri']) . '</id>' . "\r\n";
$o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
$o .= '<published>' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '</published>' . "\r\n";
$o .= '<updated>' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '</updated>' . "\r\n";
$o .= '<dfrn:env>' . base64url_encode($body, true) . '</dfrn:env>' . "\r\n";
$o .= '<content type="' . $type . '" >' . xmlify((($type === 'html') ? $htmlbody : $body)) . '</content>' . "\r\n";
$o .= '<link rel="alternate" type="text/html" href="'.xmlify($a->get_baseurl().'/display/'.$item['guid']).'" />'."\r\n";
$o .= '<status_net notice_id="'.$item['id'].'"></status_net>'."\r\n";
if($comment)
$o .= '<dfrn:comment-allow>' . intval($item['last-child']) . '</dfrn:comment-allow>' . "\r\n";
if($item['location']) {
$o .= '<dfrn:location>' . xmlify($item['location']) . '</dfrn:location>' . "\r\n";
$o .= '<poco:address><poco:formatted>' . xmlify($item['location']) . '</poco:formatted></poco:address>' . "\r\n";
}
if($item['coord'])
$o .= '<georss:point>' . xmlify($item['coord']) . '</georss:point>' . "\r\n";
if(($item['private']) || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid']))
$o .= '<dfrn:private>' . (($item['private']) ? $item['private'] : 1) . '</dfrn:private>' . "\r\n";
if($item['extid'])
$o .= '<dfrn:extid>' . xmlify($item['extid']) . '</dfrn:extid>' . "\r\n";
if($item['bookmark'])
$o .= '<dfrn:bookmark>true</dfrn:bookmark>' . "\r\n";
if($item['app'])
$o .= '<statusnet:notice_info local_id="' . $item['id'] . '" source="' . xmlify($item['app']) . '" ></statusnet:notice_info>' . "\r\n";
if($item['guid'])
$o .= '<dfrn:diaspora_guid>' . $item['guid'] . '</dfrn:diaspora_guid>' . "\r\n";
if($item['signed_text']) {
$sign = base64_encode(json_encode(array('signed_text' => $item['signed_text'],'signature' => $item['signature'],'signer' => $item['signer'])));
$o .= '<dfrn:diaspora_signature>' . xmlify($sign) . '</dfrn:diaspora_signature>' . "\r\n";
}
$verb = construct_verb($item);
$o .= '<as:verb>' . xmlify($verb) . '</as:verb>' . "\r\n";
$actobj = construct_activity_object($item);
if(strlen($actobj))
$o .= $actobj;
$actarg = construct_activity_target($item);
if(strlen($actarg))
$o .= $actarg;
$tags = item_getfeedtags($item);
if(count($tags)) {
foreach($tags as $t)
if (($type != 'html') OR ($t[0] != "@"))
$o .= '<category scheme="X-DFRN:' . xmlify($t[0]) . ':' . xmlify($t[1]) . '" term="' . xmlify($t[2]) . '" />' . "\r\n";
}
/// @TODO
/// To support these elements, the API needs to be enhanced
/// $o .= '<link rel="ostatus:conversation" href="'.xmlify($a->get_baseurl().'/display/'.$owner['nickname'].'/'.$item['parent']).'"/>'."\r\n";
/// $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";
// Deactivated since it was meant only for OStatus
//$o .= item_get_attachment($item);
$o .= item_getfeedattach($item);
$mentioned = get_mentions($item);
if($mentioned)
$o .= $mentioned;
call_hooks('atom_entry', $o);
$o .= '</entry>' . "\r\n";
return $o;
}
function fix_private_photos($s, $uid, $item = null, $cid = 0) { function fix_private_photos($s, $uid, $item = null, $cid = 0) {
if(get_config('system','disable_embedded')) if(get_config('system','disable_embedded'))
@ -4669,7 +3885,6 @@ function fix_private_photos($s, $uid, $item = null, $cid = 0) {
return($new_body); return($new_body);
} }
function has_permissions($obj) { function has_permissions($obj) {
if(($obj['allow_cid'] != '') || ($obj['allow_gid'] != '') || ($obj['deny_cid'] != '') || ($obj['deny_gid'] != '')) if(($obj['allow_cid'] != '') || ($obj['allow_gid'] != '') || ($obj['deny_cid'] != '') || ($obj['deny_gid'] != ''))
return true; return true;
@ -4730,50 +3945,6 @@ function item_getfeedtags($item) {
return $ret; return $ret;
} }
function item_get_attachment($item) {
$o = "";
$siteinfo = get_attached_data($item["body"]);
switch($siteinfo["type"]) {
case 'link':
$o = '<link rel="enclosure" href="'.xmlify($siteinfo["url"]).'" type="text/html; charset=UTF-8" length="" title="'.xmlify($siteinfo["title"]).'"/>'."\r\n";
break;
case 'photo':
$imgdata = get_photo_info($siteinfo["image"]);
$o = '<link rel="enclosure" href="'.xmlify($siteinfo["image"]).'" type="'.$imgdata["mime"].'" length="'.$imgdata["size"].'"/>'."\r\n";
break;
case 'video':
$o = '<link rel="enclosure" href="'.xmlify($siteinfo["url"]).'" type="text/html; charset=UTF-8" length="" title="'.xmlify($siteinfo["title"]).'"/>'."\r\n";
break;
default:
break;
}
return $o;
}
function item_getfeedattach($item) {
$ret = '';
$arr = explode('[/attach],',$item['attach']);
if(count($arr)) {
foreach($arr as $r) {
$matches = false;
$cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches);
if($cnt) {
$ret .= '<link rel="enclosure" href="' . xmlify($matches[1]) . '" type="' . xmlify($matches[3]) . '" ';
if(intval($matches[2]))
$ret .= 'length="' . intval($matches[2]) . '" ';
if($matches[4] !== ' ')
$ret .= 'title="' . xmlify(trim($matches[4])) . '" ';
$ret .= ' />' . "\r\n";
}
}
}
return $ret;
}
function item_expire($uid, $days, $network = "", $force = false) { function item_expire($uid, $days, $network = "", $force = false) {
if((! $uid) || ($days < 1)) if((! $uid) || ($days < 1))

View File

@ -27,7 +27,6 @@ function onepoll_run(&$argv, &$argc){
require_once('include/session.php'); require_once('include/session.php');
require_once('include/datetime.php'); require_once('include/datetime.php');
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php'); require_once('include/items.php');
require_once('include/Contact.php'); require_once('include/Contact.php');
require_once('include/email.php'); require_once('include/email.php');

View File

@ -1121,7 +1121,7 @@ function get_reshared_guid($item) {
return $guid; return $guid;
} }
function xml_add_element($doc, $parent, $element, $value = "", $attributes = array()) { function xml_create_element($doc, $element, $value = "", $attributes = array()) {
$element = $doc->createElement($element, xmlify($value)); $element = $doc->createElement($element, xmlify($value));
foreach ($attributes AS $key => $value) { foreach ($attributes AS $key => $value) {
@ -1129,7 +1129,11 @@ function xml_add_element($doc, $parent, $element, $value = "", $attributes = arr
$attribute->value = xmlify($value); $attribute->value = xmlify($value);
$element->appendChild($attribute); $element->appendChild($attribute);
} }
return $element;
}
function xml_add_element($doc, $parent, $element, $value = "", $attributes = array()) {
$element = xml_create_element($doc, $element, $value, $attributes);
$parent->appendChild($element); $parent->appendChild($element);
} }

View File

@ -3,6 +3,7 @@
require_once('include/datetime.php'); require_once('include/datetime.php');
require_once('include/diaspora.php'); require_once('include/diaspora.php');
require_once('include/queue_fn.php'); require_once('include/queue_fn.php');
require_once('include/Contact.php');
function profile_change() { function profile_change() {
@ -53,19 +54,7 @@ function profile_change() {
$about = xmlify($profile['about']); $about = xmlify($profile['about']);
require_once('include/bbcode.php'); require_once('include/bbcode.php');
$about = xmlify(strip_tags(bbcode($about))); $about = xmlify(strip_tags(bbcode($about)));
$location = ''; $location = formatted_location($profile);
if($profile['locality'])
$location .= $profile['locality'];
if($profile['region']) {
if($location)
$location .= ', ';
$location .= $profile['region'];
}
if($profile['country-name']) {
if($location)
$location .= ', ';
$location .= $profile['country-name'];
}
$location = xmlify($location); $location = xmlify($location);
$tags = ''; $tags = '';
if($profile['pub_keywords']) { if($profile['pub_keywords']) {

View File

@ -1,6 +1,7 @@
<?php <?php
require_once("boot.php"); require_once("boot.php");
require_once('include/queue_fn.php'); require_once('include/queue_fn.php');
require_once('include/dfrn.php');
function queue_run(&$argv, &$argc){ function queue_run(&$argv, &$argc){
global $a, $db; global $a, $db;
@ -179,7 +180,7 @@ function queue_run(&$argv, &$argc){
switch($contact['network']) { switch($contact['network']) {
case NETWORK_DFRN: case NETWORK_DFRN:
logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>');
$deliver_status = dfrn_deliver($owner,$contact,$data); $deliver_status = dfrn::deliver($owner,$contact,$data);
if($deliver_status == (-1)) { if($deliver_status == (-1)) {
update_queue_time($q_item['id']); update_queue_time($q_item['id']);

View File

@ -829,35 +829,6 @@ function qp($s) {
return str_replace ("%","=",rawurlencode($s)); return str_replace ("%","=",rawurlencode($s));
}} }}
if(! function_exists('get_mentions')) {
/**
* @param array $item
* @return string html for mentions #FIXME: remove html
*/
function get_mentions($item) {
$o = '';
if(! strlen($item['tag']))
return $o;
$arr = explode(',',$item['tag']);
foreach($arr as $x) {
$matches = null;
if(preg_match('/@\[url=([^\]]*)\]/',$x,$matches)) {
$o .= "\t\t" . '<link rel="ostatus:attention" href="' . $matches[1] . '" />' . "\r\n";
$o .= "\t\t" . '<link rel="mentioned" href="' . $matches[1] . '" />' . "\r\n";
}
}
if (!$item['private']) {
$o .= "\t\t".'<link rel="ostatus:attention" href="http://activityschema.org/collection/public"/>'."\r\n";
$o .= "\t\t".'<link rel="mentioned" href="http://activityschema.org/collection/public"/>'."\r\n";
}
return $o;
}}
if(! function_exists('contact_block')) { if(! function_exists('contact_block')) {
/** /**
* Get html for contact block. * Get html for contact block.
@ -1657,54 +1628,6 @@ function get_cats_and_terms($item) {
return array($categories, $folders); return array($categories, $folders);
} }
if(! function_exists('feed_hublinks')) {
/**
* return atom link elements for all of our hubs
* @return string hub link xml elements
*/
function feed_hublinks() {
$a = get_app();
$hub = get_config('system','huburl');
$hubxml = '';
if(strlen($hub)) {
$hubs = explode(',', $hub);
if(count($hubs)) {
foreach($hubs as $h) {
$h = trim($h);
if(! strlen($h))
continue;
if ($h === '[internal]')
$h = z_root() . '/pubsubhubbub';
$hubxml .= '<link rel="hub" href="' . xmlify($h) . '" />' . "\n" ;
}
}
}
return $hubxml;
}}
if(! function_exists('feed_salmonlinks')) {
/**
* return atom link elements for salmon endpoints
* @param string $nick user nickname
* @return string salmon link xml elements
*/
function feed_salmonlinks($nick) {
$a = get_app();
$salmon = '<link rel="salmon" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
// old style links that status.net still needed as of 12/2010
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
return $salmon;
}}
if(! function_exists('get_plink')) { if(! function_exists('get_plink')) {
/** /**
* get private link for item * get private link for item

View File

@ -1,6 +1,5 @@
<?php <?php
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php'); require_once('include/items.php');
require_once('include/event.php'); require_once('include/event.php');

View File

@ -1,9 +1,7 @@
<?php <?php
require_once('include/items.php'); require_once('include/items.php');
require_once('include/auth.php'); require_once('include/auth.php');
require_once('include/dfrn.php');
function dfrn_poll_init(&$a) { function dfrn_poll_init(&$a) {
@ -46,7 +44,7 @@ function dfrn_poll_init(&$a) {
logger('dfrn_poll: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $user); logger('dfrn_poll: public feed request from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $user);
header("Content-type: application/atom+xml"); header("Content-type: application/atom+xml");
echo get_feed_for($a, '', $user,$last_update); echo dfrn::feed('', $user,$last_update);
killme(); killme();
} }
@ -373,7 +371,7 @@ function dfrn_poll_post(&$a) {
} }
header("Content-type: application/atom+xml"); header("Content-type: application/atom+xml");
$o = get_feed_for($a,$dfrn_id, $a->argv[1], $last_update, $direction); $o = dfrn::feed($dfrn_id, $a->argv[1], $last_update, $direction);
echo $o; echo $o;
killme(); killme();

View File

@ -1,5 +1,5 @@
<?php <?php
require_once("include/Contact.php");
function profiles_init(&$a) { function profiles_init(&$a) {
@ -482,21 +482,7 @@ function profiles_post(&$a) {
} }
if($is_default) { if($is_default) {
$location = $locality; $location = formatted_location(array("locality" => $locality, "region" => $region, "country-name" => $country_name));
if ($region != "") {
if ($location != "")
$location .= ", ";
$location .= $region;
}
if ($country_name != "") {
if ($location != "")
$location .= ", ";
$location .= $country_name;
}
$r = q("UPDATE `contact` SET `about` = '%s', `location` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `self` = 1 AND `uid` = %d", $r = q("UPDATE `contact` SET `about` = '%s', `location` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `self` = 1 AND `uid` = %d",
dbesc($about), dbesc($about),

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:thr="http://purl.org/syndication/thread/1.0"
xmlns:at="http://purl.org/atompub/tombstones/1.0"
xmlns:media="http://purl.org/syndication/atommedia"
xmlns:dfrn="http://purl.org/macgirvin/dfrn/1.0"
xmlns:as="http://activitystrea.ms/spec/1.0/"
xmlns:georss="http://www.georss.org/georss"
xmlns:poco="http://portablecontacts.net/spec/1.0"
xmlns:ostatus="http://ostatus.org/schema/1.0"
xmlns:statusnet="http://status.net/schema/api/1/" >
<id>{{$feed_id}}</id>
<title>{{$feed_title}}</title>
<generator uri="http://friendica.com" version="{{$version}}">Friendica</generator>
<link rel="license" href="http://creativecommons.org/licenses/by/3.0/" />
<link rel="alternate" type="text/html" href="{{$alternatelink}}" />
{{$hub}}
{{$salmon}}
{{$community}}
<updated>{{$feed_updated}}</updated>
<dfrn:owner>
<name dfrn:updated="{{$namdate}}" >{{$name}}</name>
<uri dfrn:updated="{{$uridate}}" >{{$profile_page}}</uri>
<link rel="photo" type="image/jpeg" dfrn:updated="{{$picdate}}" media:width="175" media:height="175" href="{{$photo}}" />
<link rel="avatar" type="image/jpeg" dfrn:updated="{{$picdate}}" media:width="175" media:height="175" href="{{$photo}}" />
{{$birthday}}
</dfrn:owner>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:thr="http://purl.org/syndication/thread/1.0"
xmlns:at="http://purl.org/atompub/tombstones/1.0"
xmlns:media="http://purl.org/syndication/atommedia"
xmlns:dfrn="http://purl.org/macgirvin/dfrn/1.0"
xmlns:as="http://activitystrea.ms/spec/1.0/"
xmlns:georss="http://www.georss.org/georss"
xmlns:poco="http://portablecontacts.net/spec/1.0"
xmlns:ostatus="http://ostatus.org/schema/1.0"
xmlns:statusnet="http://status.net/schema/api/1/" >
<id>{{$feed_id}}</id>
<title>{{$feed_title}}</title>
<generator uri="http://friendica.com" version="{{$version}}">Friendica</generator>
<link rel="license" href="http://creativecommons.org/licenses/by/3.0/" />
<link rel="alternate" type="text/html" href="{{$alternatelink}}" />
{{$hub}}
{{$salmon}}
{{$community}}
<updated>{{$feed_updated}}</updated>
<author>
<name dfrn:updated="{{$namdate}}" >{{$name}}</name>
<uri dfrn:updated="{{$uridate}}" >{{$profile_page}}</uri>
<link rel="photo" type="image/jpeg" dfrn:updated="{{$picdate}}" media:width="175" media:height="175" href="{{$photo}}" />
<link rel="avatar" type="image/jpeg" dfrn:updated="{{$picdate}}" media:width="175" media:height="175" href="{{$photo}}" />
{{$birthday}}
</author>

View File

@ -1,18 +0,0 @@
<dfrn:mail>
<dfrn:sender>
<dfrn:name>{{$name}}</dfrn:name>
<dfrn:uri>{{$profile_page}}</dfrn:uri>
<dfrn:avatar>{{$thumb}}</dfrn:avatar>
</dfrn:sender>
<dfrn:id>{{$item_id}}</dfrn:id>
<dfrn:in-reply-to>{{$parent_id}}</dfrn:in-reply-to>
<dfrn:sentdate>{{$created}}</dfrn:sentdate>
<dfrn:subject>{{$subject}}</dfrn:subject>
<dfrn:content>{{$content}}</dfrn:content>
</dfrn:mail>

View File

@ -1,18 +0,0 @@
<dfrn:relocate>
<dfrn:url>{{$url}}</dfrn:url>
<dfrn:name>{{$name}}</dfrn:name>
<dfrn:photo>{{$photo}}</dfrn:photo>
<dfrn:thumb>{{$thumb}}</dfrn:thumb>
<dfrn:micro>{{$micro}}</dfrn:micro>
<dfrn:request>{{$request}}</dfrn:request>
<dfrn:confirm>{{$confirm}}</dfrn:confirm>
<dfrn:notify>{{$notify}}</dfrn:notify>
<dfrn:poll>{{$poll}}</dfrn:poll>
<dfrn:sitepubkey>{{$sitepubkey}}</dfrn:sitepubkey>
</dfrn:relocate>

View File

@ -1,12 +0,0 @@
<dfrn:suggest>
<dfrn:url>{{$url}}</dfrn:url>
<dfrn:name>{{$name}}</dfrn:name>
<dfrn:photo>{{$photo}}</dfrn:photo>
<dfrn:request>{{$request}}</dfrn:request>
<dfrn:note>{{$note}}</dfrn:note>
</dfrn:suggest>