2016-01-22 01:58:36 +01:00
< ? php
require_once ( 'include/items.php' );
2016-01-24 14:30:57 +01:00
require_once ( 'include/Contact.php' );
2016-01-23 01:07:51 +01:00
require_once ( 'include/ostatus.php' );
2016-01-22 01:58:36 +01:00
2016-01-23 01:07:51 +01:00
/**
2016-01-24 10:34:39 +01:00
* @ brief Generates the atom entries for delivery . php
*
* This function is used whenever content is transmitted via DFRN .
2016-01-23 01:07:51 +01:00
*
* @ param array $items Item elements
* @ param array $owner Owner record
*
* @ return string DFRN entries
*/
2016-01-22 20:26:11 +01:00
function dfrn_entries ( $items , $owner ) {
$doc = new DOMDocument ( '1.0' , 'utf-8' );
$doc -> formatOutput = true ;
2016-01-23 01:07:51 +01:00
$root = dfrn_add_header ( $doc , $owner , " dfrn:owner " , " " , false );
2016-01-22 20:26:11 +01:00
if ( ! count ( $items ))
return trim ( $doc -> saveXML ());
foreach ( $items as $item ) {
$entry = dfrn_entry ( $doc , " text " , $item , $owner , $item [ " entry:comment-allow " ], $item [ " entry:cid " ]);
$root -> appendChild ( $entry );
}
return ( trim ( $doc -> saveXML ()));
}
2016-01-23 01:07:51 +01:00
/**
2016-01-24 10:34:39 +01:00
* @ brief Generate an atom feed for the given user
*
* This function is called when another server is pulling data from the user feed .
2016-01-23 01:07:51 +01:00
*
* @ param App $a
2016-01-25 01:06:46 +01:00
* @ param string $dfrn_id DFRN ID from the requesting party
2016-01-23 01:07:51 +01:00
* @ param string $owner_nick Owner nick name
* @ param string $last_update Date of the last update
2016-01-25 01:06:46 +01:00
* @ param int $direction Can be - 1 , 0 or 1.
2016-01-23 01:07:51 +01:00
*
* @ return string DFRN feed entries
*/
2016-01-22 01:58:36 +01:00
function dfrn_feed ( & $a , $dfrn_id , $owner_nick , $last_update , $direction = 0 ) {
$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' ];
$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' ;
$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 ;
$doc = new DOMDocument ( '1.0' , 'utf-8' );
$doc -> formatOutput = true ;
2016-01-22 20:26:11 +01:00
$alternatelink = $owner [ 'url' ];
2016-01-22 01:58:36 +01:00
if ( isset ( $category ))
$alternatelink .= " /category/ " . $category ;
2016-01-23 02:44:30 +01:00
if ( $public_feed )
$author = " dfrn:owner " ;
else
$author = " author " ;
$root = dfrn_add_header ( $doc , $owner , $author , $alternatelink , true );
2016-01-22 20:26:11 +01:00
// This hook can't work anymore
// call_hooks('atom_feed', $atom);
2016-01-22 01:58:36 +01:00
if ( ! count ( $items )) {
2016-01-22 20:26:11 +01:00
$atom = trim ( $doc -> saveXML ());
2016-01-22 01:58:36 +01:00
call_hooks ( 'atom_feed_end' , $atom );
2016-01-22 20:26:11 +01:00
return $atom ;
2016-01-22 01:58:36 +01:00
}
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' ;
}
2016-01-22 20:26:11 +01:00
$entry = dfrn_entry ( $doc , $type , $item , $owner , true );
2016-01-22 01:58:36 +01:00
$root -> appendChild ( $entry );
}
2016-01-22 20:26:11 +01:00
$atom = trim ( $doc -> saveXML ());
2016-01-22 01:58:36 +01:00
2016-01-22 20:26:11 +01:00
call_hooks ( 'atom_feed_end' , $atom );
2016-01-22 01:58:36 +01:00
2016-01-22 20:26:11 +01:00
return $atom ;
2016-01-22 01:58:36 +01:00
}
/**
2016-01-24 10:34:39 +01:00
* @ brief Create XML text for DFRN mails
2016-01-23 01:07:51 +01:00
*
* @ param array $item message elements
* @ param array $owner Owner record
*
* @ return string DFRN mail
*/
function dfrn_mail ( $item , $owner ) {
$doc = new DOMDocument ( '1.0' , 'utf-8' );
$doc -> formatOutput = true ;
$root = dfrn_add_header ( $doc , $owner , " dfrn:owner " , " " , false );
$mail = $doc -> createElement ( " dfrn:mail " );
$sender = $doc -> createElement ( " dfrn:sender " );
xml_add_element ( $doc , $sender , " dfrn:name " , $owner [ 'name' ]);
xml_add_element ( $doc , $sender , " dfrn:uri " , $owner [ 'url' ]);
xml_add_element ( $doc , $sender , " dfrn:avatar " , $owner [ 'thumb' ]);
$mail -> appendChild ( $sender );
xml_add_element ( $doc , $mail , " dfrn:id " , $item [ 'uri' ]);
xml_add_element ( $doc , $mail , " dfrn:in-reply-to " , $item [ 'parent-uri' ]);
xml_add_element ( $doc , $mail , " dfrn:sentdate " , datetime_convert ( 'UTC' , 'UTC' , $item [ 'created' ] . '+00:00' , ATOM_TIME ));
xml_add_element ( $doc , $mail , " dfrn:subject " , $item [ 'title' ]);
xml_add_element ( $doc , $mail , " dfrn:content " , $item [ 'body' ]);
$root -> appendChild ( $mail );
return ( trim ( $doc -> saveXML ()));
}
/**
2016-01-24 10:34:39 +01:00
* @ brief Create XML text for DFRN friend suggestions
2016-01-23 01:07:51 +01:00
*
* @ param array $item suggestion elements
* @ param array $owner Owner record
2016-01-22 01:58:36 +01:00
*
2016-01-23 01:07:51 +01:00
* @ return string DFRN suggestions
*/
function dfrn_fsuggest ( $item , $owner ) {
$doc = new DOMDocument ( '1.0' , 'utf-8' );
$doc -> formatOutput = true ;
$root = dfrn_add_header ( $doc , $owner , " dfrn:owner " , " " , false );
$suggest = $doc -> createElement ( " dfrn:suggest " );
xml_add_element ( $doc , $suggest , " dfrn:url " , $item [ 'url' ]);
xml_add_element ( $doc , $suggest , " dfrn:name " , $item [ 'name' ]);
xml_add_element ( $doc , $suggest , " dfrn:photo " , $item [ 'photo' ]);
xml_add_element ( $doc , $suggest , " dfrn:request " , $item [ 'request' ]);
xml_add_element ( $doc , $suggest , " dfrn:note " , $item [ 'note' ]);
$root -> appendChild ( $suggest );
return ( trim ( $doc -> saveXML ()));
}
/**
* @ brief Create XML text for DFRN relocations
*
* @ param array $owner Owner record
* @ param int $uid User ID
*
* @ return string DFRN relocations
*/
function dfrn_relocate ( $owner , $uid ) {
$a = get_app ();
/* 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 );
$doc = new DOMDocument ( '1.0' , 'utf-8' );
$doc -> formatOutput = true ;
$root = dfrn_add_header ( $doc , $owner , " dfrn:owner " , " " , false );
$relocate = $doc -> createElement ( " dfrn:relocate " );
xml_add_element ( $doc , $relocate , " dfrn:url " , $owner [ 'url' ]);
xml_add_element ( $doc , $relocate , " dfrn:name " , $owner [ 'name' ]);
xml_add_element ( $doc , $relocate , " dfrn:photo " , $photos [ 4 ]);
xml_add_element ( $doc , $relocate , " dfrn:thumb " , $photos [ 5 ]);
xml_add_element ( $doc , $relocate , " dfrn:micro " , $photos [ 6 ]);
xml_add_element ( $doc , $relocate , " dfrn:request " , $owner [ 'request' ]);
xml_add_element ( $doc , $relocate , " dfrn:confirm " , $owner [ 'confirm' ]);
xml_add_element ( $doc , $relocate , " dfrn:notify " , $owner [ 'notify' ]);
xml_add_element ( $doc , $relocate , " dfrn:poll " , $owner [ 'poll' ]);
xml_add_element ( $doc , $relocate , " dfrn:sitepubkey " , get_config ( 'system' , 'site_pubkey' ));
$root -> appendChild ( $relocate );
return ( trim ( $doc -> saveXML ()));
}
/**
* @ brief Adds the header elements for the DFRN protocol
2016-01-22 01:58:36 +01:00
*
2016-01-23 01:07:51 +01:00
* @ param object $doc XML document
* @ param array $owner Owner record
* @ param string $authorelement Element name for the author
* @ param string $alternatelink link to profile or category
* @ param bool $public Is it a header for public posts ?
2016-01-22 01:58:36 +01:00
*
2016-01-23 01:07:51 +01:00
* @ return object XML root object
2016-01-22 01:58:36 +01:00
*/
2016-01-23 01:07:51 +01:00
function dfrn_add_header ( $doc , $owner , $authorelement , $alternatelink = " " , $public = false ) {
2016-01-22 20:26:11 +01:00
$a = get_app ();
if ( $alternatelink == " " )
$alternatelink = $owner [ 'url' ];
2016-01-22 01:58:36 +01:00
2016-01-22 20:26:11 +01:00
$root = $doc -> createElementNS ( NS_ATOM , 'feed' );
$doc -> appendChild ( $root );
$root -> setAttribute ( " xmlns:thr " , NS_THR );
2016-01-22 01:58:36 +01:00
$root -> setAttribute ( " xmlns:at " , " http://purl.org/atompub/tombstones/1.0 " );
2016-01-22 20:26:11 +01:00
$root -> setAttribute ( " xmlns:media " , NS_MEDIA );
$root -> setAttribute ( " xmlns:dfrn " , " http://purl.org/macgirvin/dfrn/1.0 " );
$root -> setAttribute ( " xmlns:activity " , NS_ACTIVITY );
$root -> setAttribute ( " xmlns:georss " , NS_GEORSS );
$root -> setAttribute ( " xmlns:poco " , NS_POCO );
$root -> setAttribute ( " xmlns:ostatus " , NS_OSTATUS );
$root -> setAttribute ( " xmlns:statusnet " , NS_STATUSNET );
xml_add_element ( $doc , $root , " id " , $a -> get_baseurl () . " /profile/ " . $owner [ " nick " ]);
xml_add_element ( $doc , $root , " title " , $owner [ " name " ]);
2016-01-22 01:58:36 +01:00
2016-01-22 20:26:11 +01:00
$attributes = array ( " uri " => " https://friendi.ca " , " version " => FRIENDICA_VERSION . " - " . DB_UPDATE_VERSION );
xml_add_element ( $doc , $root , " generator " , FRIENDICA_PLATFORM , $attributes );
$attributes = array ( " rel " => " license " , " href " => " http://creativecommons.org/licenses/by/3.0/ " );
2016-01-22 01:58:36 +01:00
xml_add_element ( $doc , $root , " link " , " " , $attributes );
2016-01-22 20:26:11 +01:00
$attributes = array ( " rel " => " alternate " , " type " => " text/html " , " href " => $alternatelink );
xml_add_element ( $doc , $root , " link " , " " , $attributes );
ostatus_hublinks ( $doc , $root );
2016-01-23 01:07:51 +01:00
if ( $public ) {
$attributes = array ( " rel " => " salmon " , " href " => $a -> get_baseurl () . " /salmon/ " . $owner [ " nick " ]);
xml_add_element ( $doc , $root , " link " , " " , $attributes );
2016-01-22 20:26:11 +01:00
2016-01-23 01:07:51 +01:00
$attributes = array ( " rel " => " http://salmon-protocol.org/ns/salmon-replies " , " href " => $a -> get_baseurl () . " /salmon/ " . $owner [ " nick " ]);
xml_add_element ( $doc , $root , " link " , " " , $attributes );
2016-01-22 20:26:11 +01:00
2016-01-23 01:07:51 +01:00
$attributes = array ( " rel " => " http://salmon-protocol.org/ns/salmon-mention " , " href " => $a -> get_baseurl () . " /salmon/ " . $owner [ " nick " ]);
xml_add_element ( $doc , $root , " link " , " " , $attributes );
}
2016-01-22 20:26:11 +01:00
if ( $owner [ 'page-flags' ] == PAGE_COMMUNITY )
xml_add_element ( $doc , $root , " dfrn:community " , 1 );
xml_add_element ( $doc , $root , " updated " , datetime_convert ( " UTC " , " UTC " , " now " , ATOM_TIME ));
2016-01-22 01:58:36 +01:00
2016-01-24 14:30:57 +01:00
$author = dfrn_add_author ( $doc , $owner , $authorelement , $public );
2016-01-22 01:58:36 +01:00
$root -> appendChild ( $author );
2016-01-22 20:26:11 +01:00
return $root ;
2016-01-22 01:58:36 +01:00
}
2016-01-23 01:07:51 +01:00
/**
2016-01-24 10:34:39 +01:00
* @ brief Adds the author element in the header for the DFRN protocol
2016-01-23 01:07:51 +01:00
*
* @ param object $doc XML document
* @ param array $owner Owner record
* @ param string $authorelement Element name for the author
*
* @ return object XML author object
*/
2016-01-24 14:30:57 +01:00
function dfrn_add_author ( $doc , $owner , $authorelement , $public ) {
2016-01-22 01:58:36 +01:00
$a = get_app ();
2016-01-22 20:26:11 +01:00
$author = $doc -> createElement ( $authorelement );
2016-01-22 01:58:36 +01:00
$namdate = datetime_convert ( 'UTC' , 'UTC' , $owner [ 'name-date' ] . '+00:00' , ATOM_TIME );
$uridate = datetime_convert ( 'UTC' , 'UTC' , $owner [ 'uri-date' ] . '+00:00' , ATOM_TIME );
$picdate = datetime_convert ( 'UTC' , 'UTC' , $owner [ 'avatar-date' ] . '+00:00' , ATOM_TIME );
$attributes = array ( " dfrn:updated " => $namdate );
xml_add_element ( $doc , $author , " name " , $owner [ " name " ], $attributes );
$attributes = array ( " dfrn:updated " => $namdate );
xml_add_element ( $doc , $author , " uri " , $a -> get_baseurl () . '/profile/' . $owner [ " nickname " ], $attributes );
$attributes = array ( " rel " => " photo " , " type " => " image/jpeg " , " dfrn:updated " => $picdate ,
" media:width " => 175 , " media:height " => 175 , " href " => $owner [ 'photo' ]);
xml_add_element ( $doc , $author , " link " , " " , $attributes );
$attributes = array ( " rel " => " avatar " , " type " => " image/jpeg " , " dfrn:updated " => $picdate ,
" media:width " => 175 , " media:height " => 175 , " href " => $owner [ 'photo' ]);
xml_add_element ( $doc , $author , " link " , " " , $attributes );
2016-01-22 20:26:11 +01:00
$birthday = feed_birthday ( $owner [ 'user_uid' ], $owner [ 'timezone' ]);
if ( $birthday )
xml_add_element ( $doc , $author , " dfrn:birthday " , $birthday );
2016-01-24 14:30:57 +01:00
// The following fields will only be generated if this isn't for a public feed
if ( $public )
return $author ;
// Only show contact details when we are allowed to
$r = q ( " SELECT `profile`.`about`, `profile`.`name`, `profile`.`homepage`, `user`.`nickname`, `user`.`timezone`,
`profile` . `locality` , `profile` . `region` , `profile` . `country-name` , `profile` . `pub_keywords` , `profile` . `dob`
FROM `profile`
INNER JOIN `user` ON `user` . `uid` = `profile` . `uid`
WHERE `profile` . `is-default` AND NOT `user` . `hidewall` AND `user` . `uid` = % d " ,
intval ( $owner [ 'user_uid' ]));
if ( $r ) {
$profile = $r [ 0 ];
xml_add_element ( $doc , $author , " poco:displayName " , $profile [ " name " ]);
xml_add_element ( $doc , $author , " poco:updated " , $namdate );
if ( trim ( $profile [ " dob " ]) != " 0000-00-00 " )
xml_add_element ( $doc , $author , " poco:birthday " , " 0000- " . date ( " m-d " , strtotime ( $profile [ " dob " ])));
xml_add_element ( $doc , $author , " poco:note " , $profile [ " about " ]);
xml_add_element ( $doc , $author , " poco:preferredUsername " , $profile [ " nickname " ]);
$savetz = date_default_timezone_get ();
date_default_timezone_set ( $profile [ " timezone " ]);
xml_add_element ( $doc , $author , " poco:utcOffset " , date ( " P " ));
date_default_timezone_set ( $savetz );
if ( trim ( $profile [ " homepage " ]) != " " ) {
$urls = $doc -> createElement ( " poco:urls " );
xml_add_element ( $doc , $urls , " poco:type " , " homepage " );
xml_add_element ( $doc , $urls , " poco:value " , $profile [ " homepage " ]);
xml_add_element ( $doc , $urls , " poco:primary " , " true " );
$author -> appendChild ( $urls );
}
if ( trim ( $profile [ " pub_keywords " ]) != " " ) {
$keywords = explode ( " , " , $profile [ " pub_keywords " ]);
foreach ( $keywords AS $keyword )
xml_add_element ( $doc , $author , " poco:tags " , trim ( $keyword ));
}
/// @todo When we are having the XMPP address in the profile we should propagate it here
$xmpp = " " ;
if ( trim ( $xmpp ) != " " ) {
$ims = $doc -> createElement ( " poco:ims " );
xml_add_element ( $doc , $ims , " poco:type " , " xmpp " );
xml_add_element ( $doc , $ims , " poco:value " , $xmpp );
xml_add_element ( $doc , $ims , " poco:primary " , " true " );
$author -> appendChild ( $ims );
}
if ( trim ( $profile [ " locality " ] . $profile [ " region " ] . $profile [ " country-name " ]) != " " ) {
$element = $doc -> createElement ( " poco:address " );
xml_add_element ( $doc , $element , " poco:formatted " , formatted_location ( $profile ));
if ( trim ( $profile [ " locality " ]) != " " )
xml_add_element ( $doc , $element , " poco:locality " , $profile [ " locality " ]);
if ( trim ( $profile [ " region " ]) != " " )
xml_add_element ( $doc , $element , " poco:region " , $profile [ " region " ]);
if ( trim ( $profile [ " country-name " ]) != " " )
xml_add_element ( $doc , $element , " poco:country " , $profile [ " country-name " ]);
$author -> appendChild ( $element );
}
}
2016-01-22 01:58:36 +01:00
return $author ;
}
2016-01-23 01:07:51 +01:00
/**
2016-01-24 10:34:39 +01:00
* @ brief Adds the author elements in the " entry " elements of the DFRN protocol
2016-01-23 01:07:51 +01:00
*
* @ param object $doc XML document
* @ param string $element Element name for the author
* @ param string $contact_url Link of the contact
* @ param array $items Item elements
*
* @ return object XML author object
*/
2016-01-22 20:26:11 +01:00
function dfrn_add_entry_author ( $doc , $element , $contact_url , $item ) {
2016-01-22 01:58:36 +01:00
$a = get_app ();
2016-01-22 20:26:11 +01:00
$contact = get_contact_details_by_url ( $contact_url , $item [ " uid " ]);
$author = $doc -> createElement ( $element );
xml_add_element ( $doc , $author , " name " , $contact [ " name " ]);
xml_add_element ( $doc , $author , " uri " , $contact [ " url " ]);
/// @Todo
/// - Check real image type and image size
2016-01-24 14:30:57 +01:00
/// - Check which of these boths elements we should use
2016-01-22 20:26:11 +01:00
$attributes = array (
" rel " => " photo " ,
" type " => " image/jpeg " ,
" media:width " => 80 ,
" media:height " => 80 ,
" href " => $contact [ " photo " ]);
xml_add_element ( $doc , $author , " link " , " " , $attributes );
$attributes = array (
" rel " => " avatar " ,
" type " => " image/jpeg " ,
" media:width " => 80 ,
" media:height " => 80 ,
" href " => $contact [ " photo " ]);
xml_add_element ( $doc , $author , " link " , " " , $attributes );
return $author ;
2016-01-22 01:58:36 +01:00
}
2016-01-23 01:07:51 +01:00
/**
* @ brief Adds the activity elements
*
* @ param object $doc XML document
* @ param string $element Element name for the activity
* @ param string $activity activity value
*
* @ return object XML activity object
*/
2016-01-22 20:26:11 +01:00
function dfrn_create_activity ( $doc , $element , $activity ) {
if ( $activity ) {
$entry = $doc -> createElement ( $element );
$r = parse_xml_string ( $activity , false );
if ( ! $r )
return false ;
if ( $r -> type )
xml_add_element ( $doc , $entry , " activity:object-type " , $r -> type );
if ( $r -> id )
xml_add_element ( $doc , $entry , " id " , $r -> id );
if ( $r -> title )
xml_add_element ( $doc , $entry , " title " , $r -> title );
if ( $r -> link ) {
if ( substr ( $r -> link , 0 , 1 ) === '<' ) {
if ( strstr ( $r -> link , '&' ) && ( ! strstr ( $r -> link , '&' )))
$r -> link = str_replace ( '&' , '&' , $r -> link );
$r -> link = preg_replace ( '/\<link(.*?)\"\>/' , '<link$1"/>' , $r -> link );
$data = parse_xml_string ( $r -> link , false );
foreach ( $data -> attributes () AS $parameter => $value )
$attributes [ $parameter ] = $value ;
} else
$attributes = array ( " rel " => " alternate " , " type " => " text/html " , " href " => $r -> link );
xml_add_element ( $doc , $entry , " link " , " " , $attributes );
}
if ( $r -> content )
xml_add_element ( $doc , $entry , " content " , bbcode ( $r -> content ), array ( " type " => " html " ));
2016-01-22 01:58:36 +01:00
2016-01-22 20:26:11 +01:00
return $entry ;
}
2016-01-22 01:58:36 +01:00
2016-01-22 20:26:11 +01:00
return false ;
}
2016-01-22 01:58:36 +01:00
2016-01-23 01:07:51 +01:00
/**
2016-01-24 10:34:39 +01:00
* @ brief Adds the elements for attachments
2016-01-23 01:07:51 +01:00
*
* @ param object $doc XML document
* @ param object $root XML root
* @ param array $item Item element
*
* @ return object XML attachment object
*/
2016-01-22 20:26:11 +01:00
function dfrn_get_attachment ( $doc , $root , $item ) {
$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 ) {
$attributes = array ( " rel " => " enclosure " ,
" href " => $matches [ 1 ],
" type " => $matches [ 3 ]);
if ( intval ( $matches [ 2 ]))
$attributes [ " length " ] = intval ( $matches [ 2 ]);
if ( trim ( $matches [ 4 ]) != " " )
$attributes [ " title " ] = trim ( $matches [ 4 ]);
xml_add_element ( $doc , $root , " link " , " " , $attributes );
}
}
}
2016-01-22 01:58:36 +01:00
}
2016-01-23 01:07:51 +01:00
/**
2016-01-24 10:34:39 +01:00
* @ brief Adds the " entry " elements for the DFRN protocol
2016-01-23 01:07:51 +01:00
*
* @ param object $doc XML document
* @ param string $type " text " or " html "
* @ param array $item Item element
* @ param array $owner Owner record
* @ param bool $comment Trigger the sending of the " comment " element
2016-01-25 01:06:46 +01:00
* @ param int $cid Contact ID of the recipient
2016-01-23 01:07:51 +01:00
*
* @ return object XML entry object
*/
2016-01-22 20:26:11 +01:00
function dfrn_entry ( $doc , $type , $item , $owner , $comment = false , $cid = 0 ) {
$a = get_app ();
$mentioned = array ();
if ( ! $item [ 'parent' ])
return ;
if ( $item [ 'deleted' ]) {
$attributes = array ( " ref " => $item [ 'uri' ], " when " => datetime_convert ( 'UTC' , 'UTC' , $item [ 'edited' ] . '+00:00' , ATOM_TIME ));
2016-01-23 02:44:30 +01:00
return xml_create_element ( $doc , " at:deleted-entry " , " " , $attributes );
2016-01-22 20:26:11 +01:00
}
2016-01-23 02:44:30 +01:00
$entry = $doc -> createElement ( " entry " );
2016-01-22 20:26:11 +01:00
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' ];
if ( $type == 'html' ) {
$htmlbody = $body ;
if ( $item [ 'title' ] != " " )
$htmlbody = " [b] " . $item [ 'title' ] . " [/b] \n \n " . $htmlbody ;
$htmlbody = bbcode ( $htmlbody , false , false , 7 );
}
$author = dfrn_add_entry_author ( $doc , " author " , $item [ " author-link " ], $item );
$entry -> appendChild ( $author );
$dfrnowner = dfrn_add_entry_author ( $doc , " dfrn:owner " , $item [ " owner-link " ], $item );
$entry -> appendChild ( $dfrnowner );
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' ]);
$attributes = array ( " ref " => $parent_item , " type " => " text/html " , " href " => $a -> get_baseurl () . '/display/' . $parent [ 0 ][ 'guid' ]);
xml_add_element ( $doc , $entry , " thr:in-reply-to " , " " , $attributes );
}
xml_add_element ( $doc , $entry , " id " , $item [ " uri " ]);
xml_add_element ( $doc , $entry , " title " , $item [ " title " ]);
xml_add_element ( $doc , $entry , " published " , datetime_convert ( " UTC " , " UTC " , $item [ " created " ] . " +00:00 " , ATOM_TIME ));
xml_add_element ( $doc , $entry , " updated " , datetime_convert ( " UTC " , " UTC " , $item [ " edited " ] . " +00:00 " , ATOM_TIME ));
xml_add_element ( $doc , $entry , " dfrn:env " , base64url_encode ( $body , true ));
xml_add_element ( $doc , $entry , " content " , (( $type === 'html' ) ? $htmlbody : $body ), array ( " type " => $type ));
xml_add_element ( $doc , $entry , " link " , " " , array ( " rel " => " alternate " , " type " => " text/html " ,
" href " => $a -> get_baseurl () . " /display/ " . $item [ " guid " ]));
if ( $comment )
xml_add_element ( $doc , $entry , " dfrn:comment-allow " , intval ( $item [ 'last-child' ]));
if ( $item [ 'location' ])
xml_add_element ( $doc , $entry , " dfrn:location " , $item [ 'location' ]);
if ( $item [ 'coord' ])
xml_add_element ( $doc , $entry , " georss:point " , $item [ 'coord' ]);
if (( $item [ 'private' ]) || strlen ( $item [ 'allow_cid' ]) || strlen ( $item [ 'allow_gid' ]) || strlen ( $item [ 'deny_cid' ]) || strlen ( $item [ 'deny_gid' ]))
xml_add_element ( $doc , $entry , " dfrn:private " , (( $item [ 'private' ]) ? $item [ 'private' ] : 1 ));
if ( $item [ 'extid' ])
xml_add_element ( $doc , $entry , " dfrn:extid " , $item [ 'extid' ]);
if ( $item [ 'bookmark' ])
xml_add_element ( $doc , $entry , " dfrn:bookmark " , " true " );
if ( $item [ 'app' ])
xml_add_element ( $doc , $entry , " statusnet:notice_info " , " " , array ( " local_id " => $item [ 'id' ], " source " => $item [ 'app' ]));
xml_add_element ( $doc , $entry , " dfrn:diaspora_guid " , $item [ " guid " ]);
if ( $item [ 'signed_text' ]) {
$sign = base64_encode ( json_encode ( array ( 'signed_text' => $item [ 'signed_text' ], 'signature' => $item [ 'signature' ], 'signer' => $item [ 'signer' ])));
xml_add_element ( $doc , $entry , " dfrn:diaspora_signature " , $sign );
}
xml_add_element ( $doc , $entry , " activity:verb " , construct_verb ( $item ));
$actobj = dfrn_create_activity ( $doc , " activity:object " , $item [ 'object' ]);
if ( $actobj )
$entry -> appendChild ( $actobj );
$actarg = dfrn_create_activity ( $doc , " activity:target " , $item [ 'target' ]);
if ( $actarg )
$entry -> appendChild ( $actarg );
$tags = item_getfeedtags ( $item );
if ( count ( $tags )) {
foreach ( $tags as $t )
if (( $type != 'html' ) OR ( $t [ 0 ] != " @ " ))
xml_add_element ( $doc , $entry , " category " , " " , array ( " scheme " => " X-DFRN: " . $t [ 0 ] . " : " . $t [ 1 ], " term " => $t [ 2 ]));
}
if ( count ( $tags ))
foreach ( $tags as $t )
if ( $t [ 0 ] == " @ " )
$mentioned [ $t [ 1 ]] = $t [ 1 ];
foreach ( $mentioned AS $mention ) {
$r = q ( " SELECT `forum`, `prv` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' " ,
intval ( $owner [ " uid " ]),
dbesc ( normalise_link ( $mention )));
if ( $r [ 0 ][ " forum " ] OR $r [ 0 ][ " prv " ])
xml_add_element ( $doc , $entry , " link " , " " , array ( " rel " => " mentioned " ,
" ostatus:object-type " => ACTIVITY_OBJ_GROUP ,
" href " => $mention ));
else
xml_add_element ( $doc , $entry , " link " , " " , array ( " rel " => " mentioned " ,
" ostatus:object-type " => ACTIVITY_OBJ_PERSON ,
" href " => $mention ));
}
dfrn_get_attachment ( $doc , $entry , $item );
return $entry ;
2016-01-22 01:58:36 +01:00
}