2013-02-26 01:09:40 +00:00
< ? php /** @file */
2010-07-18 13:02:55 +00:00
2011-08-20 11:53:11 +00:00
require_once ( 'include/bbcode.php' );
require_once ( 'include/oembed.php' );
require_once ( 'include/crypto.php' );
2013-04-26 03:01:24 +00:00
require_once ( 'include/photo/photo_driver.php' );
2013-01-14 02:35:12 +00:00
require_once ( 'include/permissions.php' );
2010-07-18 13:02:55 +00:00
2012-11-16 05:52:05 +00:00
2014-08-08 00:14:11 +00:00
function collect_recipients ( $item , & $private_envelope ) {
2012-11-16 05:52:05 +00:00
2012-12-08 22:18:02 +00:00
require_once ( 'include/group.php' );
2014-08-08 00:14:11 +00:00
$private_envelope = (( intval ( $item [ 'item_private' ])) ? true : false );
2014-01-23 06:07:47 +00:00
$recipients = array ();
2012-11-16 05:52:05 +00:00
if ( $item [ 'allow_cid' ] || $item [ 'allow_gid' ] || $item [ 'deny_cid' ] || $item [ 'deny_gid' ]) {
2014-01-23 06:07:47 +00:00
// it is private
2012-11-16 05:52:05 +00:00
$allow_people = expand_acl ( $item [ 'allow_cid' ]);
2014-08-31 00:03:26 +00:00
2012-11-16 05:52:05 +00:00
$allow_groups = expand_groups ( expand_acl ( $item [ 'allow_gid' ]));
2014-08-31 00:03:26 +00:00
$allow_groups = filter_insecure ( $item [ 'uid' ], $allow_groups );
2013-09-23 03:55:55 +00:00
$recipients = array_unique ( array_merge ( $allow_people , $allow_groups ));
// if you specifically deny somebody but haven't allowed anybody, we'll allow everybody in your
// address book minus the denied connections. The post is still private and can't be seen publicly
// as that would allow the denied person to see the post by logging out.
if (( ! $item [ 'allow_cid' ]) && ( ! $item [ 'allow_gid' ])) {
2014-07-02 04:24:43 +00:00
$r = q ( " select * from abook where abook_channel = %d and not (abook_flags & %d) " ,
2013-09-23 03:55:55 +00:00
intval ( $item [ 'uid' ]),
2014-07-02 04:24:43 +00:00
intval ( ABOOK_FLAG_SELF | ABOOK_FLAG_PENDING | ABOOK_FLAG_ARCHIVED )
2013-09-23 03:55:55 +00:00
);
if ( $r ) {
foreach ( $r as $rr ) {
$recipients [] = $rr [ 'abook_xchan' ];
}
}
}
2012-11-16 05:52:05 +00:00
$deny_people = expand_acl ( $item [ 'deny_cid' ]);
$deny_groups = expand_groups ( expand_acl ( $item [ 'deny_gid' ]));
$deny = array_unique ( array_merge ( $deny_people , $deny_groups ));
2014-08-31 00:03:26 +00:00
// Don't deny anybody if nobody was allowed (e.g. they were all filtered out)
// That would lead to array_diff doing the wrong thing.
// This will result in a private post that won't be delivered to anybody.
if ( $recipients && $deny )
$recipients = array_diff ( $recipients , $deny );
2014-08-08 00:14:11 +00:00
$private_envelope = true ;
2012-11-16 05:52:05 +00:00
}
else {
2014-08-08 00:14:11 +00:00
// if the post is marked private but there are no recipients and public_policy/scope = self,
// only add the author and owner as recipients. The ACL for the post may live on the hub of
// a different clone. We need to get the post to that hub.
// The post may be private by virtue of not being visible to anybody on the internet,
// but there are no envelope recipients, so set this to false. Delivery is controlled
// by the directives in $item['public_policy'].
$private_envelope = false ;
if ( array_key_exists ( 'public_policy' , $item ) && $item [ 'public_policy' ] !== 'self' ) {
2014-09-15 00:07:39 +00:00
$r = q ( " select abook_xchan, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and not (abook_flags & %d) " ,
2014-01-23 06:07:47 +00:00
intval ( $item [ 'uid' ]),
2014-07-02 04:24:43 +00:00
intval ( ABOOK_FLAG_SELF | ABOOK_FLAG_PENDING | ABOOK_FLAG_ARCHIVED )
2014-01-23 06:07:47 +00:00
);
if ( $r ) {
2014-09-15 00:07:39 +00:00
// filter out restrictive public_policy settings from remote networks
// which don't have this concept and will treat them as public.
$policy = substr ( $item [ 'public_policy' ], 0 , 3 );
2014-01-23 06:07:47 +00:00
foreach ( $r as $rr ) {
2014-09-15 00:07:39 +00:00
switch ( $policy ) {
case 'net' :
case 'aut' :
case 'sit' :
case 'any' :
case 'con' :
if ( $rr [ 'xchan_network' ] != 'zot' )
break ;
case 'pub' :
case '' :
default :
$recipients [] = $rr [ 'abook_xchan' ];
break ;
}
2014-01-23 06:07:47 +00:00
}
2012-11-16 05:52:05 +00:00
}
}
}
2013-01-14 02:35:12 +00:00
// This is a somewhat expensive operation but important.
// Don't send this item to anybody who isn't allowed to see it
$recipients = check_list_permissions ( $item [ 'uid' ], $recipients , 'view_stream' );
2014-03-31 23:29:46 +00:00
// remove any upstream recipients from our list.
// If it is ourself we'll add it back in a second.
// This should prevent complex delivery chains from getting overly complex by not
// sending to anybody who is on our list of those who sent it to us.
2014-03-31 23:25:05 +00:00
if ( $item [ 'route' ]) {
$route = explode ( ',' , $item [ 'route' ]);
2014-03-30 04:53:50 +00:00
if ( count ( $route )) {
$route = array_unique ( $route );
$recipients = array_diff ( $recipients , $route );
}
}
2013-07-14 08:12:05 +00:00
// add ourself just in case we have nomadic clones that need to get a copy.
$recipients [] = $item [ 'author_xchan' ];
if ( $item [ 'owner_xchan' ] != $item [ 'author_xchan' ])
$recipients [] = $item [ 'owner_xchan' ];
2014-08-26 05:43:44 +00:00
2012-11-16 05:52:05 +00:00
return $recipients ;
2013-01-14 02:35:12 +00:00
2012-11-16 05:52:05 +00:00
}
2014-08-31 00:03:26 +00:00
/**
* If channel is configured to filter insecure members of privacy groups
* ( those whose networks leak privacy via email notifications or other criteria )
* remove them from any privacy groups ( collections ) that were included in a post .
* They can still be addressed individually .
* Networks may need to be added or removed from this list as circumstances change .
2014-08-31 05:53:21 +00:00
*
* Update : this may need to be the default , which will force people to opt - in to sending stuff
* privately to insecure platforms .
2014-08-31 00:03:26 +00:00
*/
function filter_insecure ( $channel_id , $arr ) {
$insecure_nets = " and not xchan_network in ('diaspora', 'friendica-over-diaspora') " ;
$ret = array ();
if (( ! intval ( get_config ( $channel_id , 'system' , 'filter_insecure_collections' ))) || ( ! $arr ))
return $arr ;
$str = '' ;
foreach ( $arr as $rr ) {
if ( strlen ( $str ))
$str .= ',' ;
$str .= " ' " . dbesc ( $rr ) . " ' " ;
}
$r = q ( " select xchan_hash from xchan where xchan_hash in ( $str ) $insecure_nets " );
if ( $r ) {
foreach ( $r as $rr ) {
$ret [] = $rr [ 'xchan_hash' ];
}
}
return $ret ;
}
2014-08-28 23:56:13 +00:00
function comments_are_now_closed ( $item ) {
2014-09-09 03:35:15 +00:00
if ( $item [ 'comments_closed' ] !== NULL_DATE ) {
2014-08-28 23:56:13 +00:00
$d = datetime_convert ();
if ( $d > $item [ 'comments_closed' ])
return true ;
}
return false ;
}
2013-09-28 11:41:12 +00:00
/**
* @ function can_comment_on_post ( $observer_xchan , $item );
*
* This function examines the comment_policy attached to an item and decides if the current observer has
* sufficient privileges to comment . This will normally be called on a remote site where perm_is_allowed ()
* will not be suitable because the post owner does not have a local channel_id .
* Generally we should look at the item - in particular the author [ 'book_flags' ] and see if ABOOK_FLAG_SELF is set .
* If it is , you should be able to use perm_is_allowed ( ... 'post_comments' ), and if it isn ' t you need to call
* can_comment_on_post ()
2014-08-28 23:56:13 +00:00
* We also check the comments_closed date / time on the item if this is set .
2013-09-28 12:03:58 +00:00
*/
2014-04-24 02:05:48 +00:00
2013-06-17 03:44:29 +00:00
function can_comment_on_post ( $observer_xchan , $item ) {
2013-09-28 11:41:12 +00:00
// logger('can_comment_on_post: comment_policy: ' . $item['comment_policy'], LOGGER_DEBUG);
2013-06-17 03:44:29 +00:00
if ( ! $observer_xchan )
return false ;
2014-08-28 23:56:13 +00:00
2013-06-17 03:44:29 +00:00
if ( $item [ 'comment_policy' ] === 'none' )
return false ;
2014-08-28 23:56:13 +00:00
if ( comments_are_now_closed ( $item ))
return false ;
2013-09-21 00:58:11 +00:00
if ( $observer_xchan === $item [ 'author_xchan' ] || $observer_xchan === $item [ 'owner_xchan' ])
return true ;
2013-06-17 03:44:29 +00:00
switch ( $item [ 'comment_policy' ]) {
case 'self' :
if ( $observer_xchan === $item [ 'author_xchan' ] || $observer_xchan === $item [ 'owner_xchan' ])
return true ;
break ;
case 'public' :
2013-09-28 11:41:12 +00:00
// We don't allow public comments yet, until a policy
// for dealing with anonymous comments is in place with
// a means to moderate comments. Until that time, return
// false.
2013-06-17 03:44:29 +00:00
return false ;
break ;
2014-08-23 22:22:26 +00:00
case 'any connections' :
2013-06-17 03:44:29 +00:00
case 'contacts' :
case '' :
2013-09-21 02:14:57 +00:00
if ( array_key_exists ( 'owner' , $item )) {
if (( $item [ 'owner' ][ 'abook_xchan' ]) && ( $item [ 'owner' ][ 'abook_their_perms' ] & PERMS_W_COMMENT ))
return true ;
}
2013-06-17 03:44:29 +00:00
break ;
default :
break ;
}
2013-06-17 06:07:04 +00:00
if ( strstr ( $item [ 'comment_policy' ], 'network:' ) && strstr ( $item [ 'comment_policy' ], 'red' ))
2013-06-17 03:44:29 +00:00
return true ;
2013-06-17 06:07:04 +00:00
if ( strstr ( $item [ 'comment_policy' ], 'site:' ) && strstr ( $item [ 'comment_policy' ], get_app () -> get_hostname ()))
2013-06-17 03:44:29 +00:00
return true ;
return false ;
}
2014-04-24 02:05:48 +00:00
/**
* @ function add_source_route ( $iid , $hash )
* Adds $hash to the item source route specified by $iid
* @ param integer $iid
* item [ 'id' ] of target item
* @ param string $hash
* xchan_hash of the channel that sent the item
* Modifies item pointed to by $iid
*
* $item [ 'route' ] contains a comma - separated list of xchans that sent the current message ,
* somewhat analogous to the * Received : header line in email . We can use this to perform
* loop detection and to avoid sending a particular item to any " upstream " sender ( they
* already have a copy because they sent it to us ) .
*
*/
2013-06-17 03:44:29 +00:00
2014-03-30 04:53:50 +00:00
function add_source_route ( $iid , $hash ) {
2014-04-01 00:21:16 +00:00
// logger('add_source_route ' . $iid . ' ' . $hash, LOGGER_DEBUG);
2014-04-01 00:14:56 +00:00
2014-04-01 00:21:16 +00:00
if (( ! $iid ) || ( ! $hash ))
2014-03-30 04:53:50 +00:00
return ;
2014-03-31 23:25:05 +00:00
$r = q ( " select route from item where id = %d limit 1 " ,
2014-03-30 04:53:50 +00:00
intval ( $iid )
);
2014-03-31 23:25:05 +00:00
if ( $r ) {
$new_route = (( $r [ 0 ][ 'route' ]) ? $r [ 0 ][ 'route' ] . ',' : '' ) . $hash ;
q ( " update item set route = '%s' where id = %d limit 1 " ,
( dbesc ( $new_route )),
2014-03-30 04:53:50 +00:00
intval ( $iid )
);
}
}
2013-04-19 00:55:35 +00:00
/**
* @ function red_zrl_callback
* preg_match function when fixing 'naked' links in mod item . php
* Check if we 've got a hubloc for the site and use a zrl if we do, a url if we don' t .
2014-02-16 22:13:26 +00:00
* Remove any existing zid = param which may have been pasted by mistake - and will have
* the author 's credentials. zid' s are dynamic and can ' t really be passed around like
* that .
2013-04-19 00:55:35 +00:00
*/
function red_zrl_callback ( $matches ) {
2014-07-14 08:38:16 +00:00
require_once ( 'include/hubloc.php' );
$zrl = is_matrix_url ( $matches [ 2 ]);
2014-02-16 22:13:26 +00:00
$t = strip_zids ( $matches [ 2 ]);
if ( $t !== $matches [ 2 ]) {
$zrl = true ;
$matches [ 2 ] = $t ;
}
2014-02-08 20:08:07 +00:00
if ( $matches [ 1 ] === '#^' )
$matches [ 1 ] = '' ;
2013-04-19 00:55:35 +00:00
if ( $zrl )
2014-02-06 21:54:39 +00:00
return $matches [ 1 ] . '#^[zrl=' . $matches [ 2 ] . ']' . $matches [ 2 ] . '[/zrl]' ;
2014-02-07 00:22:40 +00:00
return $matches [ 1 ] . '#^[url=' . $matches [ 2 ] . ']' . $matches [ 2 ] . '[/url]' ;
2013-04-19 00:55:35 +00:00
}
2014-02-09 08:30:43 +00:00
// If we've got a url or zrl tag with a naked url somewhere in the link text,
// escape it with quotes unless the naked url is a linked photo.
function red_escape_zrl_callback ( $matches ) {
2014-02-09 21:46:40 +00:00
// Uncertain why the url/zrl forms weren't picked up by the non-greedy regex.
if (( strpos ( $matches [ 3 ], 'zmg' ) !== false ) || ( strpos ( $matches [ 3 ], 'img' ) !== false ) || ( strpos ( $matches [ 3 ], 'zrl' ) !== false ) || ( strpos ( $matches [ 3 ], 'url' ) !== false ))
2014-02-09 08:30:43 +00:00
return $matches [ 0 ];
return '[' . $matches [ 1 ] . 'rl' . $matches [ 2 ] . ']' . $matches [ 3 ] . '"' . $matches [ 4 ] . '"' . $matches [ 5 ] . '[/' . $matches [ 6 ] . 'rl]' ;
}
2013-04-19 00:55:35 +00:00
2014-02-10 09:11:59 +00:00
function red_escape_codeblock ( $m ) {
2014-02-10 09:44:21 +00:00
return '[$b64' . $m [ 2 ] . base64_encode ( $m [ 1 ]) . '[/' . $m [ 2 ] . ']' ;
2014-02-10 09:11:59 +00:00
}
function red_unescape_codeblock ( $m ) {
2014-02-10 09:44:21 +00:00
return '[' . $m [ 2 ] . base64_decode ( $m [ 1 ]) . '[/' . $m [ 2 ] . ']' ;
2014-02-10 09:11:59 +00:00
}
2014-05-14 03:17:52 +00:00
function red_zrlify_img_callback ( $matches ) {
2014-07-14 08:38:16 +00:00
require_once ( 'include/hubloc.php' );
$zrl = is_matrix_url ( $matches [ 2 ]);
2014-05-14 03:17:52 +00:00
$t = strip_zids ( $matches [ 2 ]);
if ( $t !== $matches [ 2 ]) {
$zrl = true ;
$matches [ 2 ] = $t ;
}
if ( $zrl )
return '[zmg' . $matches [ 1 ] . ']' . $matches [ 2 ] . '[/zmg]' ;
return $matches [ 0 ];
}
2013-04-05 01:54:24 +00:00
/**
* @ function post_activity_item ( $arr )
*
* post an activity
*
* @ param array $arr
*
* In its simplest form one needs only to set $arr [ 'body' ] to post a note to the logged in channel ' s wall .
* Much more complex activities can be created . Permissions are checked . No filtering , tag expansion
* or other processing is performed .
*
* @ returns array
* 'success' => true or false
* 'activity' => the resulting activity if successful
*/
function post_activity_item ( $arr ) {
$ret = array ( 'success' => false );
2013-06-05 03:07:13 +00:00
$is_comment = false ;
if ((( $arr [ 'parent' ]) && $arr [ 'parent' ] != $arr [ 'id' ]) || (( $arr [ 'parent_mid' ]) && $arr [ 'parent_mid' ] != $arr [ 'mid' ]))
$is_comment = true ;
2013-04-05 01:54:24 +00:00
if ( ! x ( $arr , 'item_flags' )) {
2013-06-05 03:07:13 +00:00
if ( $is_comment )
$arr [ 'item_flags' ] = ITEM_ORIGIN ;
else
$arr [ 'item_flags' ] = ITEM_ORIGIN | ITEM_WALL | ITEM_THREAD_TOP ;
2013-04-05 01:54:24 +00:00
}
2013-06-05 03:07:13 +00:00
2013-04-05 01:54:24 +00:00
$channel = get_app () -> get_channel ();
$observer = get_app () -> get_observer ();
$arr [ 'aid' ] = (( x ( $arr , 'aid' )) ? $arr [ 'aid' ] : $channel [ 'channel_account_id' ]);
$arr [ 'uid' ] = (( x ( $arr , 'uid' )) ? $arr [ 'uid' ] : $channel [ 'channel_id' ]);
2013-06-05 03:07:13 +00:00
if ( ! perm_is_allowed ( $arr [ 'uid' ], $observer [ 'xchan_hash' ],(( $is_comment ) ? 'post_comments' : 'post_wall' ))) {
2013-04-05 01:54:24 +00:00
$ret [ 'message' ] = t ( 'Permission denied' );
return $ret ;
}
2014-08-23 01:01:21 +00:00
$arr [ 'public_policy' ] = (( x ( $_REQUEST , 'public_policy' )) ? escape_tags ( $_REQUEST [ 'public_policy' ]) : map_scope ( $channel [ 'channel_r_stream' ], true ));
if ( $arr [ 'public_policy' ])
$arr [ 'item_private' ] = 1 ;
2013-05-23 01:22:41 +00:00
2013-12-08 07:29:26 +00:00
if ( ! array_key_exists ( 'mimetype' , $arr ))
$arr [ 'mimetype' ] = 'text/bbcode' ;
if ( array_key_exists ( 'item_private' , $arr ) && $arr [ 'item_private' ]) {
$arr [ 'body' ] = z_input_filter ( $arr [ 'uid' ], $arr [ 'body' ], $arr [ 'mimetype' ]);
if ( $channel ) {
if ( $channel [ 'channel_hash' ] === $arr [ 'author_xchan' ]) {
$arr [ 'sig' ] = base64url_encode ( rsa_sign ( $arr [ 'body' ], $channel [ 'channel_prvkey' ]));
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_VERIFIED ;
}
}
logger ( 'Encrypting local storage' );
$key = get_config ( 'system' , 'pubkey' );
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_OBSCURED ;
if ( $arr [ 'title' ])
2014-08-23 09:45:21 +00:00
$arr [ 'title' ] = json_encode ( crypto_encapsulate ( $arr [ 'title' ], $key ));
2013-12-08 07:29:26 +00:00
if ( $arr [ 'body' ])
2014-08-23 09:45:21 +00:00
$arr [ 'body' ] = json_encode ( crypto_encapsulate ( $arr [ 'body' ], $key ));
2013-12-08 07:29:26 +00:00
}
2013-05-23 01:22:41 +00:00
2013-04-05 01:54:24 +00:00
$arr [ 'mid' ] = (( x ( $arr , 'mid' )) ? $arr [ 'mid' ] : item_message_id ());
$arr [ 'parent_mid' ] = (( x ( $arr , 'parent_mid' )) ? $arr [ 'parent_mid' ] : $arr [ 'mid' ]);
$arr [ 'thr_parent' ] = (( x ( $arr , 'thr_parent' )) ? $arr [ 'thr_parent' ] : $arr [ 'mid' ]);
2013-04-18 04:40:40 +00:00
$arr [ 'owner_xchan' ] = (( x ( $arr , 'owner_xchan' )) ? $arr [ 'owner_xchan' ] : $channel [ 'channel_hash' ]);
2013-04-05 01:54:24 +00:00
$arr [ 'author_xchan' ] = (( x ( $arr , 'author_xchan' )) ? $arr [ 'author_xchan' ] : $observer [ 'xchan_hash' ]);
$arr [ 'verb' ] = (( x ( $arr , 'verb' )) ? $arr [ 'verb' ] : ACTIVITY_POST );
$arr [ 'obj_type' ] = (( x ( $arr , 'obj_type' )) ? $arr [ 'obj_type' ] : ACTIVITY_OBJ_NOTE );
$arr [ 'allow_cid' ] = (( x ( $arr , 'allow_cid' )) ? $arr [ 'allow_cid' ] : $channel [ 'channel_allow_cid' ]);
$arr [ 'allow_gid' ] = (( x ( $arr , 'allow_gid' )) ? $arr [ 'allow_gid' ] : $channel [ 'channel_allow_gid' ]);
$arr [ 'deny_cid' ] = (( x ( $arr , 'deny_cid' )) ? $arr [ 'deny_cid' ] : $channel [ 'channel_deny_cid' ]);
$arr [ 'deny_gid' ] = (( x ( $arr , 'deny_gid' )) ? $arr [ 'deny_gid' ] : $channel [ 'channel_deny_gid' ]);
2013-06-17 06:08:52 +00:00
$arr [ 'comment_policy' ] = map_scope ( $channel [ 'channel_w_comment' ]);
2013-05-22 04:51:02 +00:00
2014-01-09 23:45:17 +00:00
if (( ! $arr [ 'plink' ]) && ( $arr [ 'item_flags' ] & ITEM_THREAD_TOP )) {
$arr [ 'plink' ] = z_root () . '/channel/' . $channel [ 'channel_address' ] . '/?f=&mid=' . $arr [ 'mid' ];
}
2013-05-22 04:51:02 +00:00
// for the benefit of plugins, we will behave as if this is an API call rather than a normal online post
$_REQUEST [ 'api_source' ] = 1 ;
2013-05-22 04:54:21 +00:00
call_hooks ( 'post_local' , $arr );
2013-05-22 04:51:02 +00:00
if ( x ( $arr , 'cancel' )) {
logger ( 'post_activity_item: post cancelled by plugin.' );
return $ret ;
}
2013-09-11 02:06:06 +00:00
$post = item_store ( $arr );
2013-12-08 07:29:26 +00:00
if ( $post [ 'success' ])
2013-09-11 02:06:06 +00:00
$post_id = $post [ 'item_id' ];
2013-04-05 01:54:24 +00:00
if ( $post_id ) {
$arr [ 'id' ] = $post_id ;
call_hooks ( 'post_local_end' , $arr );
proc_run ( 'php' , 'include/notifier.php' , 'activity' , $post_id );
$ret [ 'success' ] = true ;
2013-05-22 03:52:18 +00:00
$r = q ( " select * from item where id = %d limit 1 " ,
intval ( $post_id )
);
if ( $r )
$ret [ 'activity' ] = $r [ 0 ];
2013-04-05 01:54:24 +00:00
}
return $ret ;
}
2014-04-24 02:05:48 +00:00
/**
* @ function get_public_feed ( $channel , $params )
* generate an Atom feed
*/
2013-04-05 01:54:24 +00:00
2012-09-21 00:04:22 +00:00
function get_public_feed ( $channel , $params ) {
$type = 'xml' ;
2014-09-09 03:35:15 +00:00
$begin = NULL_DATE ;
2012-09-21 00:04:22 +00:00
$end = '' ;
$start = 0 ;
$records = 40 ;
$direction = 'desc' ;
2013-09-06 02:31:26 +00:00
$pages = 0 ;
2012-09-21 00:04:22 +00:00
2013-06-13 03:03:04 +00:00
if ( ! $params )
$params = array ();
2013-09-06 02:31:26 +00:00
$params [ 'type' ] = (( x ( $params , 'type' )) ? $params [ 'type' ] : 'xml' );
2014-09-09 03:35:15 +00:00
$params [ 'begin' ] = (( x ( $params , 'begin' )) ? $params [ 'begin' ] : NULL_DATE );
2013-09-06 02:31:26 +00:00
$params [ 'end' ] = (( x ( $params , 'end' )) ? $params [ 'end' ] : datetime_convert ( 'UTC' , 'UTC' , 'now' ));
$params [ 'start' ] = (( x ( $params , 'start' )) ? $params [ 'start' ] : 0 );
$params [ 'records' ] = (( x ( $params , 'records' )) ? $params [ 'records' ] : 40 );
$params [ 'direction' ] = (( x ( $params , 'direction' )) ? $params [ 'direction' ] : 'desc' );
$params [ 'pages' ] = (( x ( $params , 'pages' )) ? intval ( $params [ 'pages' ]) : 0 );
2014-08-22 22:51:48 +00:00
$params [ 'top' ] = (( x ( $params , 'top' )) ? intval ( $params [ 'top' ]) : 0 );
2012-09-21 00:04:22 +00:00
2013-06-13 03:03:04 +00:00
switch ( $params [ 'type' ]) {
2012-09-21 00:04:22 +00:00
case 'json' :
header ( " Content-type: application/atom+json " );
break ;
case 'xml' :
default :
header ( " Content-type: application/atom+xml " );
break ;
}
2012-04-14 11:19:41 +00:00
2013-06-13 04:12:27 +00:00
return get_feed_for ( $channel , get_observer_hash (), $params );
2013-06-13 03:03:04 +00:00
}
2010-07-18 13:02:55 +00:00
2014-04-24 02:05:48 +00:00
2013-06-13 03:03:04 +00:00
function get_feed_for ( $channel , $observer_hash , $params ) {
2010-09-10 08:45:58 +00:00
2013-06-13 03:03:04 +00:00
if ( ! channel )
http_status_exit ( 401 );
2010-09-21 02:34:44 +00:00
2012-04-14 11:19:41 +00:00
2013-09-06 02:31:26 +00:00
if ( $params [ 'pages' ]) {
if ( ! perm_is_allowed ( $channel [ 'channel_id' ], $observer_hash , 'view_pages' ))
http_status_exit ( 403 );
}
else {
if ( ! perm_is_allowed ( $channel [ 'channel_id' ], $observer_hash , 'view_stream' ))
http_status_exit ( 403 );
}
2013-06-13 03:03:04 +00:00
$items = items_fetch ( array (
'wall' => '1' ,
'datequery' => $params [ 'begin' ],
'datequery2' => $params [ 'end' ],
'start' => $params [ 'start' ], // FIXME
'records' => $params [ 'records' ], // FIXME
'direction' => $params [ 'direction' ], // FIXME
2013-09-06 02:31:26 +00:00
'pages' => $params [ 'pages' ],
2014-08-22 22:51:48 +00:00
'order' => 'post' ,
'top' => $params [ 'top' ]
2013-06-13 03:03:04 +00:00
), $channel , $observer_hash , CLIENT_MODE_NORMAL , get_app () -> module );
2010-09-21 02:34:44 +00:00
2010-07-18 13:02:55 +00:00
2013-06-13 03:03:04 +00:00
$feed_template = get_markup_template ( 'atom_feed.tpl' );
2010-07-18 13:02:55 +00:00
$atom = '' ;
$atom .= replace_macros ( $feed_template , array (
2013-04-15 05:24:47 +00:00
'$version' => xmlify ( RED_VERSION ),
2013-06-13 04:12:27 +00:00
'$red' => xmlify ( RED_PLATFORM ),
2014-09-03 08:09:28 +00:00
'$feed_id' => xmlify ( $channel [ 'xchan_url' ]),
2013-06-13 03:03:04 +00:00
'$feed_title' => xmlify ( $channel [ 'channel_name' ]),
2010-10-31 23:38:22 +00:00
'$feed_updated' => xmlify ( datetime_convert ( 'UTC' , 'UTC' , 'now' , ATOM_TIME )) ,
2013-06-13 04:12:27 +00:00
'$hub' => '' , // feed_hublinks(),
'$salmon' => '' , // feed_salmonlinks($channel['channel_address']),
2013-06-13 03:03:04 +00:00
'$name' => xmlify ( $channel [ 'channel_name' ]),
2014-09-03 08:09:28 +00:00
'$profile_page' => xmlify ( $channel [ 'xchan_url' ]),
2013-06-13 04:12:27 +00:00
'$mimephoto' => xmlify ( $channel [ 'xchan_photo_mimetype' ]),
'$photo' => xmlify ( $channel [ 'xchan_photo_l' ]),
'$thumb' => xmlify ( $channel [ 'xchan_photo_m' ]),
2013-06-13 03:03:04 +00:00
'$picdate' => '' ,
'$uridate' => '' ,
'$namdate' => '' ,
'$birthday' => '' ,
'$community' => '' ,
2010-07-18 13:02:55 +00:00
));
2010-12-25 02:32:23 +00:00
call_hooks ( 'atom_feed' , $atom );
2013-06-13 03:03:04 +00:00
if ( $items ) {
$type = 'html' ;
foreach ( $items as $item ) {
if ( $item [ 'item_private' ])
2011-08-11 04:46:19 +00:00
continue ;
2010-09-09 03:14:17 +00:00
2013-06-13 03:03:04 +00:00
$atom .= atom_entry ( $item , $type , null , $owner , true );
}
2010-07-18 13:02:55 +00:00
}
2010-12-25 02:32:23 +00:00
call_hooks ( 'atom_feed_end' , $atom );
2010-08-14 14:55:18 +00:00
$atom .= '</feed>' . " \r \n " ;
2010-12-25 03:04:40 +00:00
2010-07-18 13:02:55 +00:00
return $atom ;
2010-09-09 03:14:17 +00:00
}
function construct_verb ( $item ) {
if ( $item [ 'verb' ])
return $item [ 'verb' ];
return ACTIVITY_POST ;
}
2010-11-03 23:48:21 +00:00
function construct_activity_object ( $item ) {
2010-09-09 03:14:17 +00:00
2010-09-17 10:10:19 +00:00
if ( $item [ 'object' ]) {
$o = '<as:object>' . " \r \n " ;
2013-06-13 04:12:27 +00:00
$r = json_decode ( $item [ 'object' ], false );
2011-06-10 08:51:14 +00:00
if ( ! $r )
return '' ;
2010-09-17 10:10:19 +00:00
if ( $r -> type )
2012-08-16 05:33:37 +00:00
$o .= '<as:obj_type>' . xmlify ( $r -> type ) . '</as:obj_type>' . " \r \n " ;
2010-09-17 10:10:19 +00:00
if ( $r -> id )
2010-10-11 03:02:29 +00:00
$o .= '<id>' . xmlify ( $r -> id ) . '</id>' . " \r \n " ;
2010-11-05 03:47:44 +00:00
if ( $r -> title )
$o .= '<title>' . xmlify ( $r -> title ) . '</title>' . " \r \n " ;
2013-06-13 04:12:27 +00:00
if ( $r -> links ) {
// FIXME!!
2011-06-10 08:51:14 +00:00
if ( substr ( $r -> link , 0 , 1 ) === '<' ) {
$r -> link = preg_replace ( '/\<link(.*?)\"\>/' , '<link$1"/>' , $r -> link );
2010-11-05 03:47:44 +00:00
$o .= $r -> link ;
2011-06-10 08:51:14 +00:00
}
2010-11-03 23:48:21 +00:00
else
$o .= '<link rel="alternate" type="text/html" href="' . xmlify ( $r -> link ) . '" />' . " \r \n " ;
}
2010-09-17 10:10:19 +00:00
if ( $r -> content )
2010-10-11 03:02:29 +00:00
$o .= '<content type="html" >' . xmlify ( bbcode ( $r -> content )) . '</content>' . " \r \n " ;
2010-09-17 10:10:19 +00:00
$o .= '</as:object>' . " \r \n " ;
return $o ;
2010-09-09 03:14:17 +00:00
}
2010-09-17 10:10:19 +00:00
2010-09-09 03:14:17 +00:00
return '' ;
2010-07-19 03:49:10 +00:00
}
2010-11-03 23:48:21 +00:00
function construct_activity_target ( $item ) {
if ( $item [ 'target' ]) {
$o = '<as:target>' . " \r \n " ;
2013-06-13 04:12:27 +00:00
$r = json_decode ( $item [ 'target' ], false );
2011-06-10 08:51:14 +00:00
if ( ! $r )
return '' ;
2010-11-03 23:48:21 +00:00
if ( $r -> type )
2012-08-16 05:33:37 +00:00
$o .= '<as:obj_type>' . xmlify ( $r -> type ) . '</as:obj_type>' . " \r \n " ;
2010-11-03 23:48:21 +00:00
if ( $r -> id )
$o .= '<id>' . xmlify ( $r -> id ) . '</id>' . " \r \n " ;
2010-11-05 03:47:44 +00:00
if ( $r -> title )
$o .= '<title>' . xmlify ( $r -> title ) . '</title>' . " \r \n " ;
2013-06-13 04:12:27 +00:00
if ( $r -> links ) {
// FIXME !!!
2011-06-10 08:51:14 +00:00
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 );
2010-11-05 03:47:44 +00:00
$o .= $r -> link ;
2011-06-10 08:51:14 +00:00
}
2010-11-03 23:48:21 +00:00
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 '' ;
2012-07-06 23:09:23 +00:00
}
/* limit_body_size ()
*
* The purpose of this function is to apply system message length limits to
* imported messages without including any embedded photos in the length
*/
2013-04-04 01:04:48 +00:00
2012-07-06 23:09:23 +00:00
function limit_body_size ( $body ) {
$maxlen = get_max_import_size ();
// If the length of the body, including the embedded images, is smaller
2012-07-07 22:20:24 +00:00
// than the maximum, then don't waste time looking for the images
2012-07-06 23:09:23 +00:00
if ( $maxlen && ( strlen ( $body ) > $maxlen )) {
2012-07-07 22:20:24 +00:00
$orig_body = $body ;
$new_body = '' ;
$textlen = 0 ;
$max_found = false ;
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
$img_start = strpos ( $orig_body , '[img' );
$img_st_close = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start ), ']' ) : false );
$img_end = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start ), '[/img]' ) : false );
while (( $img_st_close !== false ) && ( $img_end !== false )) {
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
$img_st_close ++ ; // make it point to AFTER the closing bracket
$img_end += $img_start ;
$img_end += strlen ( '[/img]' );
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
if ( ! strcmp ( substr ( $orig_body , $img_start + $img_st_close , 5 ), 'data:' )) {
// This is an embedded image
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
if ( ( $textlen + $img_start ) > $maxlen ) {
if ( $textlen < $maxlen ) {
logger ( 'limit_body_size: the limit happens before an embedded image' , LOGGER_DEBUG );
$new_body = $new_body . substr ( $orig_body , 0 , $maxlen - $textlen );
$textlen = $maxlen ;
}
2012-07-06 23:09:23 +00:00
}
2012-07-07 22:20:24 +00:00
else {
$new_body = $new_body . substr ( $orig_body , 0 , $img_start );
2012-07-08 00:47:13 +00:00
$textlen += $img_start ;
2012-07-07 22:20:24 +00:00
}
$new_body = $new_body . substr ( $orig_body , $img_start , $img_end - $img_start );
2012-07-06 23:09:23 +00:00
}
else {
2012-07-07 22:20:24 +00:00
if ( ( $textlen + $img_end ) > $maxlen ) {
if ( $textlen < $maxlen ) {
$new_body = $new_body . substr ( $orig_body , 0 , $maxlen - $textlen );
$textlen = $maxlen ;
}
}
else {
$new_body = $new_body . substr ( $orig_body , 0 , $img_end );
$textlen += $img_end ;
}
2012-07-06 23:09:23 +00:00
}
2012-07-07 22:20:24 +00:00
$orig_body = substr ( $orig_body , $img_end );
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
if ( $orig_body === false ) // in case the body ends on a closing image tag
$orig_body = '' ;
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
$img_start = strpos ( $orig_body , '[img' );
$img_st_close = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start ), ']' ) : false );
$img_end = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start ), '[/img]' ) : false );
}
2012-07-06 23:09:23 +00:00
2012-07-07 22:20:24 +00:00
if ( ( $textlen + strlen ( $orig_body )) > $maxlen ) {
if ( $textlen < $maxlen ) {
$new_body = $new_body . substr ( $orig_body , 0 , $maxlen - $textlen );
$textlen = $maxlen ;
}
2012-07-06 23:09:23 +00:00
}
else {
2012-07-07 22:20:24 +00:00
$new_body = $new_body . $orig_body ;
$textlen += strlen ( $orig_body );
2012-07-06 23:09:23 +00:00
}
2012-07-07 22:20:24 +00:00
return $new_body ;
2012-07-06 23:09:23 +00:00
}
else
return $body ;
2013-04-04 01:04:48 +00:00
}
2010-11-03 23:48:21 +00:00
2012-07-19 00:08:03 +00:00
function title_is_body ( $title , $body ) {
$title = strip_tags ( $title );
$title = trim ( $title );
$title = str_replace ( array ( " \n " , " \r " , " \t " , " " ), array ( " " , " " , " " , " " ), $title );
$body = strip_tags ( $body );
$body = trim ( $body );
$body = str_replace ( array ( " \n " , " \r " , " \t " , " " ), array ( " " , " " , " " , " " ), $body );
if ( strlen ( $title ) < strlen ( $body ))
$body = substr ( $body , 0 , strlen ( $title ));
if (( $title != $body ) and ( substr ( $title , - 3 ) == " ... " )) {
$pos = strrpos ( $title , " ... " );
if ( $pos > 0 ) {
$title = substr ( $title , 0 , $pos );
$body = substr ( $body , 0 , $pos );
}
}
return ( $title == $body );
}
2010-07-19 03:49:10 +00:00
2012-11-17 10:29:02 +00:00
function get_item_elements ( $x ) {
2012-07-30 05:43:51 +00:00
$arr = array ();
2013-12-12 07:13:36 +00:00
$arr [ 'body' ] = (( $x [ 'body' ]) ? htmlspecialchars ( $x [ 'body' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-07-30 05:43:51 +00:00
2014-10-02 09:43:07 +00:00
$key = get_config ( 'system' , 'pubkey' );
2014-08-10 06:38:33 +00:00
$maxlen = get_max_import_size ();
if ( $maxlen && mb_strlen ( $arr [ 'body' ]) > $maxlen ) {
$arr [ 'body' ] = mb_substr ( $arr [ 'body' ], 0 , $maxlen , 'UTF-8' );
logger ( 'get_item_elements: message length exceeds max_import_size: truncated' );
}
2012-11-17 10:29:02 +00:00
$arr [ 'created' ] = datetime_convert ( 'UTC' , 'UTC' , $x [ 'created' ]);
$arr [ 'edited' ] = datetime_convert ( 'UTC' , 'UTC' , $x [ 'edited' ]);
2012-07-30 05:43:51 +00:00
if ( $arr [ 'created' ] > datetime_convert ())
2012-11-17 10:29:02 +00:00
$arr [ 'created' ] = datetime_convert ();
2012-07-30 05:43:51 +00:00
if ( $arr [ 'edited' ] > datetime_convert ())
2012-11-17 10:29:02 +00:00
$arr [ 'edited' ] = datetime_convert ();
2013-11-18 03:22:24 +00:00
$arr [ 'expires' ] = (( x ( $x , 'expires' ) && $x [ 'expires' ])
? datetime_convert ( 'UTC' , 'UTC' , $x [ 'expires' ])
2014-09-09 03:35:15 +00:00
: NULL_DATE );
2013-11-18 03:22:24 +00:00
$arr [ 'commented' ] = (( x ( $x , 'commented' ) && $x [ 'commented' ])
? datetime_convert ( 'UTC' , 'UTC' , $x [ 'commented' ])
: $arr [ 'created' ]);
2014-08-28 23:56:13 +00:00
$arr [ 'comments_closed' ] = (( x ( $x , 'comments_closed' ) && $x [ 'comments_closed' ])
? datetime_convert ( 'UTC' , 'UTC' , $x [ 'comments_closed' ])
2014-09-09 03:35:15 +00:00
: NULL_DATE );
2013-11-18 03:22:24 +00:00
2013-12-12 07:13:36 +00:00
$arr [ 'title' ] = (( $x [ 'title' ]) ? htmlspecialchars ( $x [ 'title' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2013-07-30 00:30:46 +00:00
if ( mb_strlen ( $arr [ 'title' ]) > 255 )
$arr [ 'title' ] = mb_substr ( $arr [ 'title' ], 0 , 255 );
2013-12-12 07:13:36 +00:00
$arr [ 'app' ] = (( $x [ 'app' ]) ? htmlspecialchars ( $x [ 'app' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2014-03-31 23:25:05 +00:00
$arr [ 'route' ] = (( $x [ 'route' ]) ? htmlspecialchars ( $x [ 'route' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2013-12-12 07:13:36 +00:00
$arr [ 'mid' ] = (( $x [ 'message_id' ]) ? htmlspecialchars ( $x [ 'message_id' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'parent_mid' ] = (( $x [ 'message_top' ]) ? htmlspecialchars ( $x [ 'message_top' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'thr_parent' ] = (( $x [ 'message_parent' ]) ? htmlspecialchars ( $x [ 'message_parent' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-11-17 10:29:02 +00:00
2013-12-12 07:13:36 +00:00
$arr [ 'plink' ] = (( $x [ 'permalink' ]) ? htmlspecialchars ( $x [ 'permalink' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'location' ] = (( $x [ 'location' ]) ? htmlspecialchars ( $x [ 'location' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'coord' ] = (( $x [ 'longlat' ]) ? htmlspecialchars ( $x [ 'longlat' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'verb' ] = (( $x [ 'verb' ]) ? htmlspecialchars ( $x [ 'verb' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'mimetype' ] = (( $x [ 'mimetype' ]) ? htmlspecialchars ( $x [ 'mimetype' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'obj_type' ] = (( $x [ 'object_type' ]) ? htmlspecialchars ( $x [ 'object_type' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'tgt_type' ] = (( $x [ 'target_type' ]) ? htmlspecialchars ( $x [ 'target_type' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2014-08-07 00:36:07 +00:00
$arr [ 'public_policy' ] = (( $x [ 'public_scope' ]) ? htmlspecialchars ( $x [ 'public_scope' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
if ( $arr [ 'public_policy' ] === 'public' )
$arr [ 'public_policy' ] = '' ;
2014-03-31 23:25:05 +00:00
$arr [ 'comment_policy' ] = (( $x [ 'comment_scope' ]) ? htmlspecialchars ( $x [ 'comment_scope' ], ENT_COMPAT , 'UTF-8' , false ) : 'contacts' );
2013-10-03 04:04:48 +00:00
2013-12-12 07:13:36 +00:00
$arr [ 'sig' ] = (( $x [ 'signature' ]) ? htmlspecialchars ( $x [ 'signature' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2013-10-03 04:04:48 +00:00
2014-10-02 09:43:07 +00:00
$arr [ 'diaspora_meta' ] = (( $x [ 'diaspora_signature' ]) ? json_encode ( crypto_encapsulate ( $x [ 'diaspora_signature' ], $key )) : '' );
2012-11-17 20:55:59 +00:00
$arr [ 'object' ] = activity_sanitise ( $x [ 'object' ]);
$arr [ 'target' ] = activity_sanitise ( $x [ 'target' ]);
2012-07-30 05:43:51 +00:00
2013-02-01 08:49:07 +00:00
$arr [ 'attach' ] = activity_sanitise ( $x [ 'attach' ]);
2012-11-17 20:55:59 +00:00
$arr [ 'term' ] = decode_tags ( $x [ 'tags' ]);
2012-07-30 05:43:51 +00:00
2012-11-27 01:07:23 +00:00
$arr [ 'item_private' ] = (( array_key_exists ( 'flags' , $x ) && is_array ( $x [ 'flags' ]) && in_array ( 'private' , $x [ 'flags' ])) ? 1 : 0 );
2013-08-01 01:57:14 +00:00
$arr [ 'item_flags' ] = 0 ;
2012-11-27 05:20:16 +00:00
if ( array_key_exists ( 'flags' , $x ) && in_array ( 'deleted' , $x [ 'flags' ]))
$arr [ 'item_restrict' ] = ITEM_DELETED ;
2012-11-27 01:07:23 +00:00
2012-11-17 20:55:59 +00:00
// Here's the deal - the site might be down or whatever but if there's a new person you've never
// seen before sending stuff to your stream, we MUST be able to look them up and import their data from their
// hub and verify that they are legit - or else we're going to toss the post. We only need to do this
// once, and after that your hub knows them. Sure some info is in the post, but it's only a transit identifier
// and not enough info to be able to look you up from your hash - which is the only thing stored with the post.
2012-07-30 05:43:51 +00:00
2013-12-04 08:19:29 +00:00
if (( $xchan_hash = import_author_xchan ( $x [ 'author' ])) !== false )
$arr [ 'author_xchan' ] = $xchan_hash ;
2012-11-17 20:55:59 +00:00
else
return array ();
2012-07-30 05:43:51 +00:00
2013-01-29 04:51:37 +00:00
// save a potentially expensive lookup if author == owner
2014-07-15 04:21:24 +00:00
if ( $arr [ 'author_xchan' ] === make_xchan_hash ( $x [ 'owner' ][ 'guid' ], $x [ 'owner' ][ 'guid_sig' ]))
2013-01-29 04:51:37 +00:00
$arr [ 'owner_xchan' ] = $arr [ 'author_xchan' ];
else {
2013-12-04 08:19:29 +00:00
if (( $xchan_hash = import_author_xchan ( $x [ 'owner' ])) !== false )
$arr [ 'owner_xchan' ] = $xchan_hash ;
2013-01-29 04:51:37 +00:00
else
return array ();
}
2012-07-30 05:43:51 +00:00
2013-10-03 04:04:48 +00:00
if ( $arr [ 'sig' ]) {
$r = q ( " select xchan_pubkey from xchan where xchan_hash = '%s' limit 1 " ,
dbesc ( $arr [ 'author_xchan' ])
);
if ( $r && rsa_verify ( $x [ 'body' ], base64url_decode ( $arr [ 'sig' ]), $r [ 0 ][ 'xchan_pubkey' ]))
$arr [ 'item_flags' ] |= ITEM_VERIFIED ;
else
logger ( 'get_item_elements: message verification failed.' );
}
// if it's a private post, encrypt it in the DB.
// We have to do that here because we need to cleanse the input and prevent bad stuff from getting in,
// and we need plaintext to do that.
2014-09-26 03:21:23 +00:00
2013-10-03 04:04:48 +00:00
if ( intval ( $arr [ 'item_private' ])) {
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_OBSCURED ;
if ( $arr [ 'title' ])
2013-11-20 23:20:12 +00:00
$arr [ 'title' ] = json_encode ( crypto_encapsulate ( $arr [ 'title' ], $key ));
2013-10-03 04:04:48 +00:00
if ( $arr [ 'body' ])
2013-11-20 23:20:12 +00:00
$arr [ 'body' ] = json_encode ( crypto_encapsulate ( $arr [ 'body' ], $key ));
2013-10-03 04:04:48 +00:00
}
2014-09-26 03:21:23 +00:00
if ( array_key_exists ( 'revision' , $x )) {
// extended export encoding
$arr [ 'revision' ] = $x [ 'revision' ];
$arr [ 'allow_cid' ] = $x [ 'allow_cid' ];
$arr [ 'allow_gid' ] = $x [ 'allow_gid' ];
$arr [ 'deny_cid' ] = $x [ 'deny_cid' ];
$arr [ 'deny_gid' ] = $x [ 'deny_gid' ];
$arr [ 'layout_mid' ] = $x [ 'layout_mid' ];
$arr [ 'postopts' ] = $x [ 'postopts' ];
$arr [ 'resource_id' ] = $x [ 'resource_id' ];
$arr [ 'resource_type' ] = $x [ 'resource_type' ];
$arr [ 'item_restrict' ] = $x [ 'item_restrict' ];
$arr [ 'item_flags' ] = $x [ 'item_flags' ];
$arr [ 'attach' ] = $x [ 'attach' ];
}
2012-07-30 05:43:51 +00:00
return $arr ;
}
2012-12-06 00:44:07 +00:00
2012-11-17 20:55:59 +00:00
function import_author_xchan ( $x ) {
2013-01-29 04:51:37 +00:00
2013-12-04 08:19:29 +00:00
$arr = array ( 'xchan' => $x , 'xchan_hash' => '' );
call_hooks ( 'import_author_xchan' , $arr );
if ( $arr [ 'xchan_hash' ])
return $arr [ 'xchan_hash' ];
2013-01-29 04:51:37 +00:00
2013-12-04 08:19:29 +00:00
if (( ! array_key_exists ( 'network' , $x )) || ( $x [ 'network' ] === 'zot' )) {
2014-02-17 22:30:02 +00:00
$y = import_author_zot ( $x );
2013-01-29 04:51:37 +00:00
}
2014-09-04 08:13:01 +00:00
if ( ! $y )
$y = import_author_diaspora ( $x );
2013-01-29 04:51:37 +00:00
2014-02-17 22:30:02 +00:00
if ( $x [ 'network' ] === 'rss' ) {
$y = import_author_rss ( $x );
}
2014-09-12 00:27:49 +00:00
if ( $x [ 'network' ] === 'unknown' ) {
$y = import_author_unknown ( $x );
}
2014-02-17 22:30:02 +00:00
return (( $y ) ? $y : false );
}
2014-09-04 08:13:01 +00:00
function import_author_diaspora ( $x ) {
if ( ! $x [ 'address' ])
return false ;
if ( discover_by_webbie ( $x [ 'address' ])) {
$r = q ( " select xchan_hash from xchan where xchan_addr = '%s' limit 1 " ,
dbesc ( $x [ 'address' ])
);
if ( $r )
return $r [ 0 ][ 'xchan_hash' ];
}
return false ;
}
2014-02-17 22:30:02 +00:00
function import_author_rss ( $x ) {
if ( ! $x [ 'url' ])
return false ;
$r = q ( " select xchan_hash from xchan where xchan_network = 'rss' and xchan_url = '%s' limit 1 " ,
dbesc ( $x [ 'url' ])
);
if ( $r ) {
logger ( 'import_author_rss: in cache' , LOGGER_DEBUG );
return $r [ 0 ][ 'xchan_hash' ];
}
$name = trim ( $x [ 'name' ]);
2014-09-05 02:15:01 +00:00
$r = q ( " insert into xchan ( xchan_hash, xchan_guid, xchan_url, xchan_name, xchan_network )
values ( '%s' , '%s' , '%s' , '%s' , '%s' ) " ,
dbesc ( $x [ 'guid' ]),
dbesc ( $x [ 'guid' ]),
2014-02-17 22:30:02 +00:00
dbesc ( $x [ 'url' ]),
2014-02-22 22:58:12 +00:00
dbesc (( $name ) ? $name : t ( '(Unknown)' )),
2014-02-17 22:30:02 +00:00
dbesc ( 'rss' )
);
2014-09-08 23:06:15 +00:00
if ( $r && $x [ 'photo' ]) {
2014-02-17 22:30:02 +00:00
2014-09-08 23:06:15 +00:00
$photos = import_profile_photo ( $x [ 'photo' ][ 'src' ], $x [ 'url' ]);
2014-02-17 22:30:02 +00:00
if ( $photos ) {
$r = q ( " update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_url = '%s' and xchan_network = 'rss' limit 1 " ,
dbesc ( datetime_convert ( 'UTC' , 'UTC' , $arr [ 'photo_updated' ])),
dbesc ( $photos [ 0 ]),
dbesc ( $photos [ 1 ]),
dbesc ( $photos [ 2 ]),
dbesc ( $photos [ 3 ]),
dbesc ( $x [ 'url' ])
);
if ( $r )
return $x [ 'url' ];
}
}
2013-01-29 04:51:37 +00:00
2013-12-04 08:19:29 +00:00
return false ;
2014-02-17 22:30:02 +00:00
2012-11-17 20:55:59 +00:00
}
2012-07-30 05:43:51 +00:00
2014-09-12 00:27:49 +00:00
function import_author_unknown ( $x ) {
if ( ! $x [ 'url' ])
return false ;
$r = q ( " select xchan_hash from xchan where xchan_network = 'unknown' and xchan_url = '%s' limit 1 " ,
dbesc ( $x [ 'url' ])
);
if ( $r ) {
logger ( 'import_author_unknown: in cache' , LOGGER_DEBUG );
return $r [ 0 ][ 'xchan_hash' ];
}
$name = trim ( $x [ 'name' ]);
$r = q ( " insert into xchan ( xchan_hash, xchan_guid, xchan_url, xchan_name, xchan_network )
values ( '%s' , '%s' , '%s' , '%s' , '%s' ) " ,
dbesc ( $x [ 'url' ]),
dbesc ( $x [ 'url' ]),
dbesc ( $x [ 'url' ]),
dbesc (( $name ) ? $name : t ( '(Unknown)' )),
dbesc ( 'unknown' )
);
if ( $r && $x [ 'photo' ]) {
$photos = import_profile_photo ( $x [ 'photo' ][ 'src' ], $x [ 'url' ]);
if ( $photos ) {
$r = q ( " update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_url = '%s' and xchan_network = 'unknown' limit 1 " ,
dbesc ( datetime_convert ( 'UTC' , 'UTC' , $arr [ 'photo_updated' ])),
dbesc ( $photos [ 0 ]),
dbesc ( $photos [ 1 ]),
dbesc ( $photos [ 2 ]),
dbesc ( $photos [ 3 ]),
dbesc ( $x [ 'url' ])
);
if ( $r )
return $x [ 'url' ];
}
}
return false ;
}
2014-09-16 10:33:48 +00:00
function encode_item ( $item , $mirror = false ) {
2012-11-15 07:09:25 +00:00
$x = array ();
2012-11-20 04:45:12 +00:00
$x [ 'type' ] = 'activity' ;
2014-07-24 22:55:01 +00:00
$x [ 'encoding' ] = 'zot' ;
2012-11-15 07:09:25 +00:00
2013-10-03 04:04:48 +00:00
// logger('encode_item: ' . print_r($item,true));
2012-11-16 05:52:05 +00:00
2013-06-17 06:20:36 +00:00
$r = q ( " select channel_r_stream, channel_w_comment from channel where channel_id = %d limit 1 " ,
2013-02-15 04:17:30 +00:00
intval ( $item [ 'uid' ])
);
2014-08-08 22:27:17 +00:00
if ( $r )
2013-06-17 02:14:01 +00:00
$comment_scope = $r [ 0 ][ 'channel_w_comment' ];
2014-08-08 22:27:17 +00:00
else
2013-06-17 02:14:01 +00:00
$comment_scope = 0 ;
2013-02-15 04:17:30 +00:00
2014-08-09 22:21:15 +00:00
$scope = $item [ 'public_policy' ];
2014-08-08 22:27:17 +00:00
if ( ! $scope )
$scope = 'public' ;
2013-06-17 02:14:01 +00:00
$c_scope = map_scope ( $comment_scope );
2013-02-15 04:17:30 +00:00
2014-09-16 10:33:48 +00:00
$key = get_config ( 'system' , 'prvkey' );
2013-07-29 04:04:03 +00:00
if ( array_key_exists ( 'item_flags' , $item ) && ( $item [ 'item_flags' ] & ITEM_OBSCURED )) {
if ( $item [ 'title' ])
2013-11-20 23:20:12 +00:00
$item [ 'title' ] = crypto_unencapsulate ( json_decode_plus ( $item [ 'title' ]), $key );
2013-07-29 04:04:03 +00:00
if ( $item [ 'body' ])
2013-11-20 23:20:12 +00:00
$item [ 'body' ] = crypto_unencapsulate ( json_decode_plus ( $item [ 'body' ]), $key );
2013-07-29 04:04:03 +00:00
}
2014-09-16 10:33:48 +00:00
// If we're trying to backup an item so that it's recoverable or for export/imprt,
// add all the attributes we need to recover it
if ( $mirror ) {
$x [ 'id' ] = $item [ 'id' ];
$x [ 'parent' ] = $item [ 'parent' ];
$x [ 'uid' ] = $item [ 'uid' ];
$x [ 'allow_cid' ] = $item [ 'allow_cid' ];
$x [ 'allow_gid' ] = $item [ 'allow_gid' ];
$x [ 'deny_cid' ] = $item [ 'deny_cid' ];
$x [ 'deny_gid' ] = $item [ 'deny_gid' ];
$x [ 'revision' ] = $item [ 'revision' ];
$x [ 'layout_mid' ] = $item [ 'layout_mid' ];
$x [ 'postopts' ] = $item [ 'postopts' ];
$x [ 'resource_id' ] = $item [ 'resource_id' ];
$x [ 'resource_type' ] = $item [ 'resource_type' ];
$x [ 'item_restrict' ] = $item [ 'item_restrict' ];
$x [ 'item_flags' ] = $item [ 'item_flags' ];
$x [ 'attach' ] = $item [ 'attach' ];
}
2012-11-16 21:57:55 +00:00
2014-08-28 23:56:13 +00:00
$x [ 'message_id' ] = $item [ 'mid' ];
$x [ 'message_top' ] = $item [ 'parent_mid' ];
$x [ 'message_parent' ] = $item [ 'thr_parent' ];
$x [ 'created' ] = $item [ 'created' ];
$x [ 'edited' ] = $item [ 'edited' ];
$x [ 'expires' ] = $item [ 'expires' ];
$x [ 'commented' ] = $item [ 'commented' ];
$x [ 'mimetype' ] = $item [ 'mimetype' ];
$x [ 'title' ] = $item [ 'title' ];
$x [ 'body' ] = $item [ 'body' ];
$x [ 'app' ] = $item [ 'app' ];
$x [ 'verb' ] = $item [ 'verb' ];
$x [ 'object_type' ] = $item [ 'obj_type' ];
$x [ 'target_type' ] = $item [ 'tgt_type' ];
$x [ 'permalink' ] = $item [ 'plink' ];
$x [ 'location' ] = $item [ 'location' ];
$x [ 'longlat' ] = $item [ 'coord' ];
$x [ 'signature' ] = $item [ 'sig' ];
$x [ 'route' ] = $item [ 'route' ];
$x [ 'owner' ] = encode_item_xchan ( $item [ 'owner' ]);
$x [ 'author' ] = encode_item_xchan ( $item [ 'author' ]);
2012-11-16 05:52:05 +00:00
if ( $item [ 'object' ])
2014-08-28 23:56:13 +00:00
$x [ 'object' ] = json_decode_plus ( $item [ 'object' ]);
2012-11-16 05:52:05 +00:00
if ( $item [ 'target' ])
2014-08-28 23:56:13 +00:00
$x [ 'target' ] = json_decode_plus ( $item [ 'target' ]);
2012-11-16 05:52:05 +00:00
if ( $item [ 'attach' ])
2014-08-28 23:56:13 +00:00
$x [ 'attach' ] = json_decode_plus ( $item [ 'attach' ]);
2012-11-16 21:57:55 +00:00
if ( $y = encode_item_flags ( $item ))
2014-08-28 23:56:13 +00:00
$x [ 'flags' ] = $y ;
2013-02-15 04:17:30 +00:00
2014-09-09 03:35:15 +00:00
if ( $item [ 'comments_closed' ] !== NULL_DATE )
2014-08-28 23:56:13 +00:00
$x [ 'comments_closed' ] = $item [ 'comments_closed' ];
$x [ 'public_scope' ] = $scope ;
2013-02-15 04:17:30 +00:00
2013-06-17 02:14:01 +00:00
if ( $item [ 'item_flags' ] & ITEM_NOCOMMENT )
$x [ 'comment_scope' ] = 'none' ;
else
$x [ 'comment_scope' ] = $c_scope ;
2012-11-16 05:52:05 +00:00
if ( $item [ 'term' ])
2014-08-28 23:56:13 +00:00
$x [ 'tags' ] = encode_item_terms ( $item [ 'term' ]);
2012-11-15 07:09:25 +00:00
2014-10-02 09:43:07 +00:00
if ( $item [ 'diaspora_meta' ])
$x [ 'diaspora_signature' ] = crypto_unencapsulate ( json_decode ( $item [ 'diaspora_meta' ], true ), $key );
2014-03-24 01:26:48 +00:00
logger ( 'encode_item: ' . print_r ( $x , true ), LOGGER_DATA );
2013-10-03 04:04:48 +00:00
2012-11-15 07:09:25 +00:00
return $x ;
2012-08-16 06:15:29 +00:00
}
2013-02-15 04:17:30 +00:00
2014-08-07 02:24:46 +00:00
function map_scope ( $scope , $strip = false ) {
2013-02-15 04:17:30 +00:00
switch ( $scope ) {
2013-02-15 22:13:58 +00:00
case 0 :
return 'self' ;
2013-02-15 04:17:30 +00:00
case PERMS_PUBLIC :
2014-08-07 02:24:46 +00:00
if ( $strip )
return '' ;
2013-02-15 04:17:30 +00:00
return 'public' ;
case PERMS_NETWORK :
return 'network: red' ;
2014-08-07 02:24:46 +00:00
case PERMS_AUTHED :
return 'authenticated' ;
2013-02-15 04:17:30 +00:00
case PERMS_SITE :
return 'site: ' . get_app () -> get_hostname ();
2014-06-17 07:26:18 +00:00
case PERMS_PENDING :
return 'any connections' ;
2013-02-15 04:17:30 +00:00
case PERMS_CONTACTS :
default :
return 'contacts' ;
}
}
2014-08-07 02:24:46 +00:00
function translate_scope ( $scope ) {
if ( ! $scope || $scope === 'public' )
2014-08-08 01:22:50 +00:00
return t ( 'Visible to anybody on the internet.' );
2014-08-07 02:24:46 +00:00
if ( strpos ( $scope , 'self' ) === 0 )
return t ( 'Visible to you only.' );
if ( strpos ( $scope , 'network:' ) === 0 )
return t ( 'Visible to anybody in this network.' );
if ( strpos ( $scope , 'authenticated' ) === 0 )
return t ( 'Visible to anybody authenticated.' );
if ( strpos ( $scope , 'site:' ) === 0 )
return sprintf ( t ( 'Visible to anybody on %s.' ), strip_tags ( substr ( $scope , 6 )));
if ( strpos ( $scope , 'any connections' ) === 0 )
return t ( 'Visible to all connections.' );
if ( strpos ( $scope , 'contacts' ) === 0 )
return t ( 'Visible to approved connections.' );
2014-08-28 11:14:49 +00:00
if ( strpos ( $scope , 'specific' ) === 0 )
return t ( 'Visible to specific connections.' );
2014-08-07 02:24:46 +00:00
}
2013-02-15 04:17:30 +00:00
2012-11-16 05:52:05 +00:00
function encode_item_xchan ( $xchan ) {
2012-08-16 06:15:29 +00:00
2012-11-16 05:52:05 +00:00
$ret = array ();
$ret [ 'name' ] = $xchan [ 'xchan_name' ];
$ret [ 'address' ] = $xchan [ 'xchan_addr' ];
2014-09-05 02:15:01 +00:00
$ret [ 'url' ] = (( $xchan [ 'hubloc_url' ]) ? $xchan [ 'hubloc_url' ] : $xchan [ 'xchan_url' ]);
2013-12-04 08:19:29 +00:00
$ret [ 'network' ] = $xchan [ 'xchan_network' ];
2012-11-16 05:52:05 +00:00
$ret [ 'photo' ] = array ( 'mimetype' => $xchan [ 'xchan_photo_mimetype' ], 'src' => $xchan [ 'xchan_photo_m' ]);
$ret [ 'guid' ] = $xchan [ 'xchan_guid' ];
$ret [ 'guid_sig' ] = $xchan [ 'xchan_guid_sig' ];
return $ret ;
}
2012-08-16 06:15:29 +00:00
2012-11-16 05:52:05 +00:00
function encode_item_terms ( $terms ) {
$ret = array ();
2014-02-04 03:38:15 +00:00
$allowed_export_terms = array ( TERM_UNKNOWN , TERM_HASHTAG , TERM_MENTION , TERM_CATEGORY , TERM_BOOKMARK );
2012-11-16 05:52:05 +00:00
if ( $terms ) {
foreach ( $terms as $term ) {
if ( in_array ( $term [ 'type' ], $allowed_export_terms ))
2012-11-17 20:55:59 +00:00
$ret [] = array ( 'tag' => $term [ 'term' ], 'url' => $term [ 'url' ], 'type' => termtype ( $term [ 'type' ]));
2012-11-16 05:52:05 +00:00
}
}
return $ret ;
}
function termtype ( $t ) {
2014-02-04 03:38:15 +00:00
$types = array ( 'unknown' , 'hashtag' , 'mention' , 'category' , 'private_category' , 'file' , 'search' , 'thing' , 'bookmark' );
2012-11-16 05:52:05 +00:00
return (( $types [ $t ]) ? $types [ $t ] : 'unknown' );
}
2010-07-19 03:49:10 +00:00
2012-11-17 20:55:59 +00:00
function decode_tags ( $t ) {
if ( $t ) {
$ret = array ();
foreach ( $t as $x ) {
$tag = array ();
2013-12-12 07:13:36 +00:00
$tag [ 'term' ] = htmlspecialchars ( $x [ 'tag' ], ENT_COMPAT , 'UTF-8' , false );
$tag [ 'url' ] = htmlspecialchars ( $x [ 'url' ], ENT_COMPAT , 'UTF-8' , false );
2012-11-17 20:55:59 +00:00
switch ( $x [ 'type' ]) {
case 'hashtag' :
$tag [ 'type' ] = TERM_HASHTAG ;
break ;
case 'mention' :
$tag [ 'type' ] = TERM_MENTION ;
break ;
case 'category' :
$tag [ 'type' ] = TERM_CATEGORY ;
break ;
case 'private_category' :
$tag [ 'type' ] = TERM_PCATEGORY ;
break ;
case 'file' :
$tag [ 'type' ] = TERM_FILE ;
break ;
case 'search' :
$tag [ 'type' ] = TERM_SEARCH ;
break ;
2014-02-04 03:38:15 +00:00
case 'thing' :
$tag [ 'type' ] = TERM_THING ;
break ;
case 'bookmark' :
$tag [ 'type' ] = TERM_BOOKMARK ;
break ;
2012-11-17 20:55:59 +00:00
default :
case 'unknown' :
$tag [ 'type' ] = TERM_UNKNOWN ;
break ;
}
$ret [] = $tag ;
}
return $ret ;
}
return '' ;
}
2012-12-22 12:33:32 +00:00
// santise a potentially complex array
2012-11-17 20:55:59 +00:00
function activity_sanitise ( $arr ) {
if ( $arr ) {
2013-08-18 07:04:38 +00:00
if ( is_array ( $arr )) {
$ret = array ();
foreach ( $arr as $k => $x ) {
if ( is_array ( $x ))
$ret [ $k ] = activity_sanitise ( $x );
else
2013-12-12 07:13:36 +00:00
$ret [ $k ] = htmlspecialchars ( $x , ENT_COMPAT , 'UTF-8' , false );
2013-08-18 07:04:38 +00:00
}
return $ret ;
}
else {
2013-12-12 07:13:36 +00:00
return htmlspecialchars ( $arr , ENT_COMPAT , 'UTF-8' , false );
2012-11-17 20:55:59 +00:00
}
}
return '' ;
}
2012-11-16 21:57:55 +00:00
2012-12-22 12:33:32 +00:00
// sanitise a simple linear array
function array_sanitise ( $arr ) {
if ( $arr ) {
$ret = array ();
foreach ( $arr as $x ) {
2013-12-12 07:13:36 +00:00
$ret [] = htmlspecialchars ( $x , ENT_COMPAT , 'UTF-8' , false );
2012-12-22 12:33:32 +00:00
}
return $ret ;
}
return '' ;
}
2012-11-16 21:57:55 +00:00
function encode_item_flags ( $item ) {
// most of item_flags and item_restrict are local settings which don't apply when transmitted.
// We may need those for the case of syncing other hub locations which you are attached to.
$ret = array ();
2014-04-10 23:26:27 +00:00
if ( $item [ 'item_restrict' ] & ITEM_DELETED )
$ret [] = 'deleted' ;
2012-11-27 00:48:04 +00:00
if ( $item [ 'item_flags' ] & ITEM_THREAD_TOP )
2012-11-16 21:57:55 +00:00
$ret [] = 'thread_parent' ;
2012-11-27 00:48:04 +00:00
if ( $item [ 'item_flags' ] & ITEM_NSFW )
2012-11-16 21:57:55 +00:00
$ret [] = 'nsfw' ;
2012-11-27 01:07:23 +00:00
if ( $item [ 'item_private' ])
2012-11-17 10:29:02 +00:00
$ret [] = 'private' ;
2012-11-16 21:57:55 +00:00
return $ret ;
}
2012-12-06 00:44:07 +00:00
function encode_mail ( $item ) {
$x = array ();
$x [ 'type' ] = 'mail' ;
2014-07-24 22:55:01 +00:00
$x [ 'encoding' ] = 'zot' ;
2012-12-06 00:44:07 +00:00
2013-07-31 09:32:41 +00:00
if ( array_key_exists ( 'mail_flags' , $item ) && ( $item [ 'mail_flags' ] & MAIL_OBSCURED )) {
$key = get_config ( 'system' , 'prvkey' );
if ( $item [ 'title' ])
2013-11-20 23:20:12 +00:00
$item [ 'title' ] = crypto_unencapsulate ( json_decode_plus ( $item [ 'title' ]), $key );
2013-07-31 09:32:41 +00:00
if ( $item [ 'body' ])
2013-11-20 23:20:12 +00:00
$item [ 'body' ] = crypto_unencapsulate ( json_decode_plus ( $item [ 'body' ]), $key );
2013-07-31 09:32:41 +00:00
}
2012-12-06 00:44:07 +00:00
2013-03-22 01:25:41 +00:00
$x [ 'message_id' ] = $item [ 'mid' ];
$x [ 'message_parent' ] = $item [ 'parent_mid' ];
2012-12-06 00:44:07 +00:00
$x [ 'created' ] = $item [ 'created' ];
2013-11-07 02:28:36 +00:00
$x [ 'expires' ] = $item [ 'expires' ];
2014-09-03 12:09:43 +00:00
$x [ 'diaspora_meta' ] = $item [ 'diaspora_meta' ];
2012-12-06 00:44:07 +00:00
$x [ 'title' ] = $item [ 'title' ];
$x [ 'body' ] = $item [ 'body' ];
$x [ 'from' ] = encode_item_xchan ( $item [ 'from' ]);
$x [ 'to' ] = encode_item_xchan ( $item [ 'to' ]);
2013-08-20 04:19:39 +00:00
if ( $item [ 'attach' ])
$x [ 'attach' ] = json_decode_plus ( $item [ 'attach' ]);
2013-07-19 09:45:44 +00:00
$x [ 'flags' ] = array ();
2013-02-28 04:38:33 +00:00
if ( $item [ 'mail_flags' ] & MAIL_RECALLED ) {
2013-07-19 09:45:44 +00:00
$x [ 'flags' ][] = 'recalled' ;
2013-02-28 04:38:33 +00:00
$x [ 'title' ] = '' ;
$x [ 'body' ] = '' ;
}
2012-12-06 00:44:07 +00:00
return $x ;
}
function get_mail_elements ( $x ) {
$arr = array ();
2013-12-12 07:13:36 +00:00
$arr [ 'body' ] = (( $x [ 'body' ]) ? htmlspecialchars ( $x [ 'body' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'title' ] = (( $x [ 'title' ]) ? htmlspecialchars ( $x [ 'title' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-12-06 00:44:07 +00:00
$arr [ 'created' ] = datetime_convert ( 'UTC' , 'UTC' , $x [ 'created' ]);
2014-09-09 03:35:15 +00:00
if (( ! array_key_exists ( 'expires' , $x )) || ( $x [ 'expires' ] === NULL_DATE ))
$arr [ 'expires' ] = NULL_DATE ;
2013-11-07 02:28:36 +00:00
else
$arr [ 'expires' ] = datetime_convert ( 'UTC' , 'UTC' , $x [ 'expires' ]);
2012-12-06 00:44:07 +00:00
2013-02-28 04:38:33 +00:00
$arr [ 'mail_flags' ] = 0 ;
if ( $x [ 'flags' ] && is_array ( $x [ 'flags' ])) {
if ( in_array ( 'recalled' , $x [ 'flags' ])) {
2013-07-19 09:45:44 +00:00
$arr [ 'mail_flags' ] |= MAIL_RECALLED ;
}
2013-02-28 04:38:33 +00:00
}
2013-07-31 09:32:41 +00:00
$key = get_config ( 'system' , 'pubkey' );
$arr [ 'mail_flags' ] |= MAIL_OBSCURED ;
2013-12-12 07:13:36 +00:00
$arr [ 'body' ] = htmlspecialchars ( $arr [ 'body' ], ENT_COMPAT , 'UTF-8' , false );
2013-07-31 09:32:41 +00:00
if ( $arr [ 'body' ])
2013-11-20 23:20:12 +00:00
$arr [ 'body' ] = json_encode ( crypto_encapsulate ( $arr [ 'body' ], $key ));
2013-12-12 07:13:36 +00:00
$arr [ 'title' ] = htmlspecialchars ( $arr [ 'title' ], ENT_COMPAT , 'UTF-8' , false );
2013-07-31 09:32:41 +00:00
if ( $arr [ 'title' ])
2013-11-20 23:20:12 +00:00
$arr [ 'title' ] = json_encode ( crypto_encapsulate ( $arr [ 'title' ], $key ));
2013-02-28 04:38:33 +00:00
2012-12-06 00:44:07 +00:00
if ( $arr [ 'created' ] > datetime_convert ())
$arr [ 'created' ] = datetime_convert ();
2013-12-12 07:13:36 +00:00
$arr [ 'mid' ] = (( $x [ 'message_id' ]) ? htmlspecialchars ( $x [ 'message_id' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'parent_mid' ] = (( $x [ 'message_parent' ]) ? htmlspecialchars ( $x [ 'message_parent' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-12-06 00:44:07 +00:00
2013-08-20 04:19:39 +00:00
if ( $x [ 'attach' ])
$arr [ 'attach' ] = activity_sanitise ( $x [ 'attach' ]);
2013-12-04 08:19:29 +00:00
if (( $xchan_hash = import_author_xchan ( $x [ 'from' ])) !== false )
$arr [ 'from_xchan' ] = $xchan_hash ;
2012-12-06 00:44:07 +00:00
else
return array ();
2013-12-04 08:19:29 +00:00
if (( $xchan_hash = import_author_xchan ( $x [ 'to' ])) !== false )
$arr [ 'to_xchan' ] = $xchan_hash ;
2012-12-06 00:44:07 +00:00
else
return array ();
return $arr ;
}
2012-12-22 12:33:32 +00:00
function get_profile_elements ( $x ) {
$arr = array ();
2013-12-04 08:19:29 +00:00
if (( $xchan_hash = import_author_xchan ( $x [ 'from' ])) !== false )
$arr [ 'xprof_hash' ] = $xchan_hash ;
2012-12-22 12:33:32 +00:00
else
return array ();
2013-12-12 07:13:36 +00:00
$arr [ 'desc' ] = (( $x [ 'title' ]) ? htmlspecialchars ( $x [ 'title' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-12-22 12:33:32 +00:00
$arr [ 'dob' ] = datetime_convert ( 'UTC' , 'UTC' , $x [ 'birthday' ], 'Y-m-d' );
2013-06-30 07:38:02 +00:00
$arr [ 'age' ] = (( $x [ 'age' ]) ? intval ( $x [ 'age' ]) : 0 );
2012-12-22 12:33:32 +00:00
2013-12-12 07:13:36 +00:00
$arr [ 'gender' ] = (( $x [ 'gender' ]) ? htmlspecialchars ( $x [ 'gender' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'marital' ] = (( $x [ 'marital' ]) ? htmlspecialchars ( $x [ 'marital' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'sexual' ] = (( $x [ 'sexual' ]) ? htmlspecialchars ( $x [ 'sexual' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'locale' ] = (( $x [ 'locale' ]) ? htmlspecialchars ( $x [ 'locale' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'region' ] = (( $x [ 'region' ]) ? htmlspecialchars ( $x [ 'region' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'postcode' ] = (( $x [ 'postcode' ]) ? htmlspecialchars ( $x [ 'postcode' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
$arr [ 'country' ] = (( $x [ 'country' ]) ? htmlspecialchars ( $x [ 'country' ], ENT_COMPAT , 'UTF-8' , false ) : '' );
2012-12-22 12:33:32 +00:00
$arr [ 'keywords' ] = (( $x [ 'keywords' ] && is_array ( $x [ 'keywords' ])) ? array_sanitise ( $x [ 'keywords' ]) : array ());
return $arr ;
}
2012-12-06 00:44:07 +00:00
2014-08-21 01:35:36 +00:00
function get_atom_elements ( $feed , $item , & $author ) {
2010-07-19 03:49:10 +00:00
2010-09-09 03:14:17 +00:00
2010-10-25 03:39:24 +00:00
$best_photo = array ();
2010-07-19 03:49:10 +00:00
2010-10-25 03:39:24 +00:00
$res = array ();
2010-09-09 03:14:17 +00:00
2014-08-21 01:35:36 +00:00
$found_author = $item -> get_author ();
if ( $found_author ) {
$author [ 'author_name' ] = unxmlify ( $found_author -> get_name ());
$author [ 'author_link' ] = unxmlify ( $found_author -> get_link ());
2014-09-24 21:27:18 +00:00
$author [ 'author_is_feed' ] = false ;
2011-04-05 02:36:18 +00:00
}
else {
2014-08-21 01:35:36 +00:00
$author [ 'author_name' ] = unxmlify ( $feed -> get_title ());
$author [ 'author_link' ] = unxmlify ( $feed -> get_permalink ());
2014-09-24 21:27:18 +00:00
$author [ 'author_is_feed' ] = true ;
2011-04-05 02:36:18 +00:00
}
2014-08-20 04:31:33 +00:00
2014-09-24 03:55:22 +00:00
if ( substr ( $author [ 'author_link' ], - 1 , 1 ) == '/' )
$author [ 'author_link' ] = substr ( $author [ 'author_link' ], 0 , - 1 );
2014-09-09 23:28:33 +00:00
$res [ 'mid' ] = base64url_encode ( unxmlify ( $item -> get_id ()));
2010-07-19 03:49:10 +00:00
$res [ 'title' ] = unxmlify ( $item -> get_title ());
$res [ 'body' ] = unxmlify ( $item -> get_content ());
2011-02-16 10:07:11 +00:00
$res [ 'plink' ] = unxmlify ( $item -> get_link ( 0 ));
2014-09-24 03:36:10 +00:00
$res [ 'item_flags' ] = ITEM_RSS ;
2010-10-25 03:39:24 +00:00
2012-07-19 00:08:03 +00:00
// removing the content of the title if its identically to the body
// This helps with auto generated titles e.g. from tumblr
2013-05-28 08:40:27 +00:00
2012-07-19 00:08:03 +00:00
if ( title_is_body ( $res [ " title " ], $res [ " body " ]))
$res [ 'title' ] = " " ;
2012-01-18 00:30:32 +00:00
if ( $res [ 'plink' ])
$base_url = implode ( '/' , array_slice ( explode ( '/' , $res [ 'plink' ]), 0 , 3 ));
else
$base_url = '' ;
2010-10-25 03:39:24 +00:00
// look for a photo. We should check media size and find the best one,
// but for now let's just find any author photo
$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 ) {
2014-08-21 01:35:36 +00:00
if ( ! x ( $author , 'author_photo' ) || ! $author [ 'author_photo' ]) {
2010-10-25 03:39:24 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'photo' || $link [ 'attribs' ][ '' ][ 'rel' ] === 'avatar' )
2014-08-21 01:35:36 +00:00
$author [ 'author_photo' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
2010-10-25 03:39:24 +00:00
}
}
2012-07-19 00:08:03 +00:00
}
2010-10-25 03:39:24 +00:00
$rawactor = $item -> get_item_tags ( NAMESPACE_ACTIVITY , 'actor' );
2012-08-16 05:33:37 +00:00
if ( $rawactor && activity_match ( $rawactor [ 0 ][ 'child' ][ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ], ACTIVITY_OBJ_PERSON )) {
2010-10-25 03:39:24 +00:00
$base = $rawactor [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ];
if ( $base && count ( $base )) {
foreach ( $base as $link ) {
2014-08-20 04:31:33 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'alternate' && ( ! $res [ 'author_link' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_link' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
if ( ! x ( $author , 'author_photo' ) || ! $author [ 'author_photo' ]) {
2010-10-25 03:39:24 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'avatar' || $link [ 'attribs' ][ '' ][ 'rel' ] === 'photo' )
2014-08-21 01:35:36 +00:00
$author [ 'author_photo' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
2010-10-25 03:39:24 +00:00
}
}
}
}
2014-09-12 00:27:49 +00:00
// check for a yahoo media element (github etc.)
if ( ! $author [ 'author_photo' ]) {
$rawmedia = $item -> get_item_tags ( NAMESPACE_YMEDIA , 'thumbnail' );
if ( $rawmedia && $rawmedia [ 0 ][ 'attribs' ][ '' ][ 'url' ]) {
$author [ 'author_photo' ] = strip_tags ( unxmlify ( $rawmedia [ 0 ][ 'attribs' ][ '' ][ 'url' ]));
}
}
2010-10-25 03:39:24 +00:00
// No photo/profile-link on the item - look at the feed level
2014-08-21 01:35:36 +00:00
if (( ! ( x ( $author , 'author_link' ))) || ( ! ( x ( $author , 'author_photo' )))) {
2010-10-25 03:39:24 +00:00
$rawauthor = $feed -> get_feed_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 ) {
2014-09-24 21:27:18 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'alternate' && ( ! $author [ 'author_link' ])) {
2014-08-21 01:35:36 +00:00
$author [ 'author_link' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
2014-09-24 21:27:18 +00:00
$author [ 'author_is_feed' ] = true ;
}
2014-08-21 01:35:36 +00:00
if ( ! $author [ 'author_photo' ]) {
2010-10-25 03:39:24 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'photo' || $link [ 'attribs' ][ '' ][ 'rel' ] === 'avatar' )
2014-08-21 01:35:36 +00:00
$author [ 'author_photo' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
2010-10-25 03:39:24 +00:00
}
}
2012-07-19 00:08:03 +00:00
}
2010-10-25 03:39:24 +00:00
$rawactor = $feed -> get_feed_tags ( NAMESPACE_ACTIVITY , 'subject' );
2012-08-16 05:33:37 +00:00
if ( $rawactor && activity_match ( $rawactor [ 0 ][ 'child' ][ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ], ACTIVITY_OBJ_PERSON )) {
2010-10-25 03:39:24 +00:00
$base = $rawactor [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ];
if ( $base && count ( $base )) {
foreach ( $base as $link ) {
2014-08-20 04:31:33 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'alternate' && ( ! $res [ 'author_link' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_link' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
if ( ! ( x ( $author , 'author_photo' ))) {
2010-10-25 03:39:24 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'avatar' || $link [ 'attribs' ][ '' ][ 'rel' ] === 'photo' )
2014-08-21 01:35:36 +00:00
$author [ 'author_photo' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
2010-10-25 03:39:24 +00:00
}
}
}
}
}
2011-06-21 02:08:40 +00:00
$apps = $item -> get_item_tags ( NAMESPACE_STATUSNET , 'notice_info' );
if ( $apps && $apps [ 0 ][ 'attribs' ][ '' ][ 'source' ]) {
2011-06-23 22:58:43 +00:00
$res [ 'app' ] = strip_tags ( unxmlify ( $apps [ 0 ][ 'attribs' ][ '' ][ 'source' ]));
2011-06-21 02:08:40 +00:00
}
2010-10-25 03:39:24 +00:00
2011-02-01 13:10:04 +00:00
/**
* If there ' s a copy of the body content which is guaranteed to have survived mangling in transit , use it .
*/
$have_real_body = false ;
$rawenv = $item -> get_item_tags ( NAMESPACE_DFRN , 'env' );
if ( $rawenv ) {
$have_real_body = true ;
$res [ 'body' ] = $rawenv [ 0 ][ 'data' ];
$res [ 'body' ] = str_replace ( array ( ' ' , " \t " , " \r " , " \n " ), array ( '' , '' , '' , '' ), $res [ 'body' ]);
2011-02-02 01:50:49 +00:00
// make sure nobody is trying to sneak some html tags by us
$res [ 'body' ] = notags ( base64url_decode ( $res [ 'body' ]));
2014-08-21 06:01:25 +00:00
// We could probably turn these old Friendica bbcode bookmarks into bookmark tags but we'd have to
// create a term table item for them. For now just make sure they stay as links.
2014-09-29 22:41:47 +00:00
$res [ 'body' ] = preg_replace ( '/\[bookmark(.*?)\](.*?)\[\/bookmark\]/' , '[url$1]$2[/url]' , $res [ 'body' ]);
2014-08-21 06:01:25 +00:00
2011-02-01 13:10:04 +00:00
}
2012-07-06 23:09:23 +00:00
$res [ 'body' ] = limit_body_size ( $res [ 'body' ]);
2010-07-19 03:49:10 +00:00
2010-09-09 03:14:17 +00:00
// It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust
// the content type. Our own network only emits text normally, though it might have been converted to
2011-01-18 03:50:18 +00:00
// html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will
2010-09-09 03:14:17 +00:00
// have to assume it is all html and needs to be purified.
// It doesn't matter all that much security wise - because before this content is used anywhere, we are
// going to escape any tags we find regardless, but this lets us import a limited subset of html from
// the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining
// html.
2012-04-01 10:19:37 +00:00
if (( strpos ( $res [ 'body' ], '<' ) !== false ) && ( strpos ( $res [ 'body' ], '>' ) !== false )) {
2010-09-09 03:14:17 +00:00
2012-01-18 00:30:32 +00:00
$res [ 'body' ] = reltoabs ( $res [ 'body' ], $base_url );
2011-10-12 01:24:37 +00:00
$res [ 'body' ] = html2bb_video ( $res [ 'body' ]);
2011-05-20 22:46:41 +00:00
2011-02-02 02:20:25 +00:00
$res [ 'body' ] = oembed_html2bbcode ( $res [ 'body' ]);
2011-02-17 01:32:15 +00:00
2013-05-28 08:40:27 +00:00
$res [ 'body' ] = purify_html ( $res [ 'body' ]);
2010-09-09 09:00:54 +00:00
2012-04-01 10:19:37 +00:00
$res [ 'body' ] = @ html2bbcode ( $res [ 'body' ]);
2012-06-20 12:04:51 +00:00
2011-01-18 03:50:18 +00:00
}
2012-04-01 22:43:57 +00:00
elseif ( ! $have_real_body ) {
// it's not one of our messages and it has no tags
// so it's probably just text. We'll escape it just to be safe.
$res [ 'body' ] = escape_tags ( $res [ 'body' ]);
}
2014-09-24 09:18:13 +00:00
if ( $res [ 'plink' ] && $res [ 'title' ]) {
$res [ 'body' ] = '#^[url=' . $res [ 'plink' ] . ']' . $res [ 'title' ] . '[/url]' . " \n \n " . $res [ 'body' ];
$terms = array ();
$terms [] = array (
'otype' => TERM_OBJ_POST ,
'type' => TERM_BOOKMARK ,
'url' => $res [ 'plink' ],
'term' => $res [ 'title' ],
);
}
elseif ( $res [ 'plink' ]) {
$res [ 'body' ] = '#^[url]' . $res [ 'plink' ] . '[/url]' . " \n \n " . $res [ 'body' ];
$terms = array ();
$terms [] = array (
'otype' => TERM_OBJ_POST ,
'type' => TERM_BOOKMARK ,
'url' => $res [ 'plink' ],
'term' => $res [ 'plink' ],
);
2014-09-24 08:45:57 +00:00
}
2014-09-24 09:18:13 +00:00
2010-12-08 04:47:53 +00:00
$private = $item -> get_item_tags ( NAMESPACE_DFRN , 'private' );
2012-06-29 00:43:29 +00:00
if ( $private && intval ( $private [ 0 ][ 'data' ]) > 0 )
2014-08-20 04:31:33 +00:00
$res [ 'item_private' ] = (( intval ( $private [ 0 ][ 'data' ])) ? 1 : 0 );
2010-12-08 04:47:53 +00:00
else
2014-08-20 04:31:33 +00:00
$res [ 'item_private' ] = 0 ;
2010-12-08 04:47:53 +00:00
2010-08-24 23:25:02 +00:00
$rawlocation = $item -> get_item_tags ( NAMESPACE_DFRN , 'location' );
2010-08-20 21:33:15 +00:00
if ( $rawlocation )
$res [ 'location' ] = unxmlify ( $rawlocation [ 0 ][ 'data' ]);
2011-01-25 03:36:20 +00:00
$rawcreated = $item -> get_item_tags ( SIMPLEPIE_NAMESPACE_ATOM_10 , 'published' );
if ( $rawcreated )
$res [ 'created' ] = unxmlify ( $rawcreated [ 0 ][ 'data' ]);
2010-07-19 03:49:10 +00:00
$rawedited = $item -> get_item_tags ( SIMPLEPIE_NAMESPACE_ATOM_10 , 'updated' );
if ( $rawedited )
2011-02-02 00:50:19 +00:00
$res [ 'edited' ] = unxmlify ( $rawedited [ 0 ][ 'data' ]);
2010-07-19 03:49:10 +00:00
2011-02-02 00:50:19 +00:00
if (( x ( $res , 'edited' )) && ( ! ( x ( $res , 'created' ))))
2011-02-02 01:05:17 +00:00
$res [ 'created' ] = $res [ 'edited' ];
2011-01-25 03:36:20 +00:00
if ( ! $res [ 'created' ])
2011-02-02 00:50:19 +00:00
$res [ 'created' ] = $item -> get_date ( 'c' );
2011-01-25 03:36:20 +00:00
if ( ! $res [ 'edited' ])
2011-02-02 00:50:19 +00:00
$res [ 'edited' ] = $item -> get_date ( 'c' );
2011-01-25 03:36:20 +00:00
2011-03-15 01:34:58 +00:00
// Disallow time travelling posts
$d1 = strtotime ( $res [ 'created' ]);
$d2 = strtotime ( $res [ 'edited' ]);
$d3 = strtotime ( 'now' );
if ( $d1 > $d3 )
$res [ 'created' ] = datetime_convert ();
if ( $d2 > $d3 )
$res [ 'edited' ] = datetime_convert ();
2014-09-01 03:51:05 +00:00
$res [ 'created' ] = datetime_convert ( 'UTC' , 'UTC' , $res [ 'created' ]);
$res [ 'edited' ] = datetime_convert ( 'UTC' , 'UTC' , $res [ 'edited' ]);
2010-08-03 02:06:36 +00:00
$rawowner = $item -> get_item_tags ( NAMESPACE_DFRN , 'owner' );
2014-08-21 01:35:36 +00:00
if ( ! $rawowner )
$rawowner = $item -> get_item_tags ( NAMESPACE_ZOT , 'owner' );
2010-09-09 03:14:17 +00:00
if ( $rawowner [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'name' ][ 0 ][ 'data' ])
2014-08-21 01:35:36 +00:00
$author [ 'owner_name' ] = unxmlify ( $rawowner [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'name' ][ 0 ][ 'data' ]);
2010-09-09 03:14:17 +00:00
elseif ( $rawowner [ 0 ][ 'child' ][ NAMESPACE_DFRN ][ 'name' ][ 0 ][ 'data' ])
2014-08-21 01:35:36 +00:00
$author [ 'owner_name' ] = unxmlify ( $rawowner [ 0 ][ 'child' ][ NAMESPACE_DFRN ][ 'name' ][ 0 ][ 'data' ]);
2010-09-09 03:14:17 +00:00
if ( $rawowner [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'uri' ][ 0 ][ 'data' ])
2014-08-21 01:35:36 +00:00
$author [ 'owner_link' ] = unxmlify ( $rawowner [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'uri' ][ 0 ][ 'data' ]);
2010-09-09 03:14:17 +00:00
elseif ( $rawowner [ 0 ][ 'child' ][ NAMESPACE_DFRN ][ 'uri' ][ 0 ][ 'data' ])
2014-08-21 01:35:36 +00:00
$author [ 'owner_link' ] = unxmlify ( $rawowner [ 0 ][ 'child' ][ NAMESPACE_DFRN ][ 'uri' ][ 0 ][ 'data' ]);
2010-09-09 03:14:17 +00:00
2010-10-25 03:39:24 +00:00
if ( $rawowner [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ]) {
$base = $rawowner [ 0 ][ 'child' ][ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ];
foreach ( $base as $link ) {
2014-08-21 01:35:36 +00:00
if ( ! x ( $author , 'owner_photo' ) || ! $author [ 'owner_photo' ]) {
2012-07-19 00:08:03 +00:00
if ( $link [ 'attribs' ][ '' ][ 'rel' ] === 'photo' || $link [ 'attribs' ][ '' ][ 'rel' ] === 'avatar' )
2014-08-21 01:35:36 +00:00
$author [ 'owner_photo' ] = unxmlify ( $link [ 'attribs' ][ '' ][ 'href' ]);
2010-10-25 03:39:24 +00:00
}
}
}
2010-07-19 03:49:10 +00:00
2010-10-20 03:52:05 +00:00
$rawgeo = $item -> get_item_tags ( NAMESPACE_GEORSS , 'point' );
if ( $rawgeo )
$res [ 'coord' ] = unxmlify ( $rawgeo [ 0 ][ 'data' ]);
2010-10-22 04:48:22 +00:00
2010-09-09 03:14:17 +00:00
$rawverb = $item -> get_item_tags ( NAMESPACE_ACTIVITY , 'verb' );
2011-01-04 10:20:00 +00:00
2010-09-09 03:14:17 +00:00
// select between supported verbs
2011-01-04 10:20:00 +00:00
if ( $rawverb ) {
2010-09-09 03:14:17 +00:00
$res [ 'verb' ] = unxmlify ( $rawverb [ 0 ][ 'data' ]);
2011-01-04 10:20:00 +00:00
}
// translate OStatus unfollow to activity streams if it happened to get selected
if (( x ( $res , 'verb' )) && ( $res [ 'verb' ] === 'http://ostatus.org/schema/1.0/unfollow' ))
$res [ 'verb' ] = ACTIVITY_UNFOLLOW ;
2011-04-06 00:41:02 +00:00
$cats = $item -> get_categories ();
if ( $cats ) {
2014-09-24 08:58:24 +00:00
if ( is_null ( $terms ))
$terms = array ();
2011-04-06 00:41:02 +00:00
foreach ( $cats as $cat ) {
$term = $cat -> get_term ();
if ( ! $term )
$term = $cat -> get_label ();
$scheme = $cat -> get_scheme ();
2012-07-11 11:29:47 +00:00
$termurl = '' ;
if ( $scheme && $term && stristr ( $scheme , 'X-DFRN:' )) {
$termtype = (( substr ( $scheme , 7 , 1 ) === '#' ) ? TERM_HASHTAG : TERM_MENTION );
$termurl = unxmlify ( substr ( $scheme , 9 ));
}
else {
2014-09-01 05:15:00 +00:00
$termtype = TERM_CATEGORY ;
2012-07-11 11:29:47 +00:00
}
$termterm = notags ( trim ( unxmlify ( $term )));
if ( $termterm ) {
2014-09-01 03:51:05 +00:00
$terms [] = array (
2012-07-11 11:29:47 +00:00
'otype' => TERM_OBJ_POST ,
'type' => $termtype ,
'url' => $termurl ,
'term' => $termterm ,
);
}
2011-04-06 00:41:02 +00:00
}
}
2010-09-09 03:14:17 +00:00
2014-09-24 09:08:35 +00:00
if ( ! is_null ( $terms ))
$res [ 'term' ] = $terms ;
2011-04-07 02:41:16 +00:00
$attach = $item -> get_enclosures ();
if ( $attach ) {
2014-08-20 04:31:33 +00:00
$res [ 'attach' ] = array ();
2011-04-07 02:41:16 +00:00
$att_arr = array ();
foreach ( $attach as $att ) {
2011-04-13 08:53:40 +00:00
$len = intval ( $att -> get_length ());
$link = str_replace ( array ( ',' , '"' ), array ( '%2D' , '%22' ), notags ( trim ( unxmlify ( $att -> get_link ()))));
$title = str_replace ( array ( ',' , '"' ), array ( '%2D' , '%22' ), notags ( trim ( unxmlify ( $att -> get_title ()))));
$type = str_replace ( array ( ',' , '"' ), array ( '%2D' , '%22' ), notags ( trim ( unxmlify ( $att -> get_type ()))));
if ( strpos ( $type , ';' ))
$type = substr ( $type , 0 , strpos ( $type , ';' ));
2011-04-07 02:41:16 +00:00
if (( ! $link ) || ( strpos ( $link , 'http' ) !== 0 ))
continue ;
if ( ! $title )
$title = ' ' ;
if ( ! $type )
$type = 'application/octet-stream' ;
2014-09-02 03:59:53 +00:00
$res [ 'attach' ][] = array ( 'href' => $link , 'length' => $len , 'type' => $type , 'title' => $title );
2011-04-07 02:41:16 +00:00
}
}
2010-09-09 03:14:17 +00:00
$rawobj = $item -> get_item_tags ( NAMESPACE_ACTIVITY , 'object' );
2010-09-17 10:10:19 +00:00
2010-09-09 03:14:17 +00:00
if ( $rawobj ) {
2014-08-20 04:31:33 +00:00
$obj = array ();
2012-04-17 11:33:50 +00:00
$child = $rawobj [ 0 ][ 'child' ];
2012-08-16 05:33:37 +00:00
if ( $child [ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ]) {
$res [ 'obj_type' ] = $child [ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ];
2014-08-20 04:31:33 +00:00
$obj [ 'type' ] = $child [ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ];
2010-09-17 10:10:19 +00:00
}
2012-04-17 11:33:50 +00:00
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'id' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'id' ][ 0 ][ 'data' ])
2014-08-20 04:31:33 +00:00
$obj [ 'id' ] = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'id' ][ 0 ][ 'data' ];
2012-04-17 11:33:50 +00:00
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'link' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ])
2014-08-20 04:31:33 +00:00
$obj [ 'link' ] = encode_rel_links ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ]);
2012-04-17 11:33:50 +00:00
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'title' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'title' ][ 0 ][ 'data' ])
2014-08-20 04:31:33 +00:00
$obj [ 'title' ] = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'title' ][ 0 ][ 'data' ];
2012-04-17 11:33:50 +00:00
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'content' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'content' ][ 0 ][ 'data' ]) {
$body = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'content' ][ 0 ][ 'data' ];
2010-09-17 10:10:19 +00:00
if ( ! $body )
2012-04-17 11:33:50 +00:00
$body = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'summary' ][ 0 ][ 'data' ];
2011-01-12 21:21:37 +00:00
// preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
2014-08-20 04:31:33 +00:00
$obj [ 'orig' ] = xmlify ( $body );
2011-02-02 02:20:25 +00:00
if (( strpos ( $body , '<' ) !== false ) || ( strpos ( $body , '>' ) !== false )) {
2010-09-17 10:10:19 +00:00
2013-09-30 03:34:05 +00:00
$body = purify_html ( $body );
2011-01-18 03:50:18 +00:00
$body = html2bbcode ( $body );
2013-09-30 03:34:05 +00:00
2010-09-17 10:10:19 +00:00
}
2014-08-20 04:31:33 +00:00
$obj [ 'content' ] = $body ;
2010-09-17 10:10:19 +00:00
}
2014-08-20 04:31:33 +00:00
$res [ 'object' ] = $obj ;
2010-09-09 03:14:17 +00:00
}
2010-11-03 23:48:21 +00:00
$rawobj = $item -> get_item_tags ( NAMESPACE_ACTIVITY , 'target' );
if ( $rawobj ) {
2014-08-20 04:31:33 +00:00
$obj = array ();
2012-04-17 11:33:50 +00:00
$child = $rawobj [ 0 ][ 'child' ];
2012-08-16 05:33:37 +00:00
if ( $child [ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ]) {
2014-08-20 04:31:33 +00:00
$res [ 'tgt_type' ] = $child [ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ];
$obj [ 'type' ] = $child [ NAMESPACE_ACTIVITY ][ 'obj_type' ][ 0 ][ 'data' ];
2010-11-03 23:48:21 +00:00
}
2012-04-17 11:33:50 +00:00
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'id' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'id' ][ 0 ][ 'data' ])
2014-08-20 04:31:33 +00:00
$obj [ 'id' ] = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'id' ][ 0 ][ 'data' ];
2012-04-17 11:33:50 +00:00
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'link' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ])
2014-08-20 04:31:33 +00:00
$obj [ 'link' ] = encode_rel_links ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'link' ]);
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'title' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'title' ][ 0 ][ 'data' ])
$obj [ 'title' ] = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'title' ][ 0 ][ 'data' ];
if ( x ( $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ], 'content' ) && $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'content' ][ 0 ][ 'data' ]) {
2012-04-17 11:33:50 +00:00
$body = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'content' ][ 0 ][ 'data' ];
2010-11-03 23:48:21 +00:00
if ( ! $body )
2012-04-17 11:33:50 +00:00
$body = $child [ SIMPLEPIE_NAMESPACE_ATOM_10 ][ 'summary' ][ 0 ][ 'data' ];
2011-01-12 21:21:37 +00:00
// preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
2014-08-20 04:31:33 +00:00
$obj [ 'orig' ] = xmlify ( $body );
2011-02-02 02:20:25 +00:00
if (( strpos ( $body , '<' ) !== false ) || ( strpos ( $body , '>' ) !== false )) {
2010-11-03 23:48:21 +00:00
2013-09-30 03:34:05 +00:00
$body = purify_html ( $body );
2011-01-18 03:50:18 +00:00
$body = html2bbcode ( $body );
2014-08-20 04:31:33 +00:00
2010-11-03 23:48:21 +00:00
}
2014-08-20 04:31:33 +00:00
$obj [ 'content' ] = $body ;
2010-11-03 23:48:21 +00:00
}
2014-08-20 04:31:33 +00:00
$res [ 'target' ] = $obj ;
2010-11-03 23:48:21 +00:00
}
2014-09-01 03:51:05 +00:00
$res [ 'public_policy' ] = 'specific' ;
$res [ 'comment_policy' ] = 'none' ;
2010-12-25 23:01:02 +00:00
$arr = array ( 'feed' => $feed , 'item' => $item , 'result' => $res );
call_hooks ( 'parse_atom' , $arr );
2014-08-21 01:35:36 +00:00
logger ( 'get_atom_elements: author: ' . print_r ( $author , true ), LOGGER_DATA );
2014-09-21 21:46:12 +00:00
2014-08-21 01:35:36 +00:00
logger ( 'get_atom_elements: ' . print_r ( $res , true ), LOGGER_DATA );
2010-12-25 02:32:23 +00:00
2010-07-19 03:49:10 +00:00
return $res ;
}
2010-11-03 23:48:21 +00:00
function encode_rel_links ( $links ) {
$o = '' ;
if ( ! (( is_array ( $links )) && ( count ( $links ))))
return $o ;
2014-08-20 04:31:33 +00:00
2010-11-03 23:48:21 +00:00
foreach ( $links as $link ) {
$o .= '<link ' ;
if ( $link [ 'attribs' ][ '' ][ 'rel' ])
$o .= 'rel="' . $link [ 'attribs' ][ '' ][ 'rel' ] . '" ' ;
if ( $link [ 'attribs' ][ '' ][ 'type' ])
$o .= 'type="' . $link [ 'attribs' ][ '' ][ 'type' ] . '" ' ;
if ( $link [ 'attribs' ][ '' ][ 'href' ])
2011-01-18 00:06:22 +00:00
$o .= 'href="' . $link [ 'attribs' ][ '' ][ 'href' ] . '" ' ;
2010-11-04 07:37:29 +00:00
if ( ( x ( $link [ 'attribs' ], NAMESPACE_MEDIA )) && $link [ 'attribs' ][ NAMESPACE_MEDIA ][ 'width' ])
2010-11-03 23:48:21 +00:00
$o .= 'media:width="' . $link [ 'attribs' ][ NAMESPACE_MEDIA ][ 'width' ] . '" ' ;
2010-11-04 07:37:29 +00:00
if ( ( x ( $link [ 'attribs' ], NAMESPACE_MEDIA )) && $link [ 'attribs' ][ NAMESPACE_MEDIA ][ 'height' ])
2010-11-03 23:48:21 +00:00
$o .= 'media:height="' . $link [ 'attribs' ][ NAMESPACE_MEDIA ][ 'height' ] . '" ' ;
$o .= ' />' . " \n " ;
}
return xmlify ( $o );
}
2013-08-11 23:56:06 +00:00
function item_store ( $arr , $allow_exec = false ) {
2010-07-19 03:49:10 +00:00
2013-11-29 02:10:04 +00:00
$d = array ( 'item' => $arr , 'allow_exec' => $allow_exec );
call_hooks ( 'item_store' , $d );
$arr = $d [ 'item' ];
$allow_exec = $d [ 'allow_exec' ];
2014-03-05 03:57:54 +00:00
$ret = array ( 'success' => false , 'item_id' => 0 );
2013-09-11 02:06:06 +00:00
2012-07-16 10:32:42 +00:00
if ( ! $arr [ 'uid' ]) {
logger ( 'item_store: no uid' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'No uid.' ;
2014-08-30 00:31:40 +00:00
return $ret ;
2012-07-16 10:32:42 +00:00
}
2013-10-14 01:36:28 +00:00
$uplinked_comment = false ;
2013-09-02 02:15:08 +00:00
// If a page layout is provided, ensure it exists and belongs to us.
if ( array_key_exists ( 'layout_mid' , $arr ) && $arr [ 'layout_mid' ]) {
$l = q ( " select item_restrict from item where mid = '%s' and uid = %d limit 1 " ,
dbesc ( $arr [ 'layout_mid' ]),
intval ( $arr [ 'uid' ])
);
if (( ! $l ) || ( ! ( $l [ 0 ][ 'item_restrict' ] & ITEM_PDL )))
unset ( $arr [ 'layout_mid' ]);
}
2013-07-16 01:07:23 +00:00
// Don't let anybody set these, either intentionally or accidentally
if ( array_key_exists ( 'id' , $arr ))
unset ( $arr [ 'id' ]);
if ( array_key_exists ( 'parent' , $arr ))
unset ( $arr [ 'parent' ]);
2013-08-02 02:18:05 +00:00
$arr [ 'mimetype' ] = (( x ( $arr , 'mimetype' )) ? notags ( trim ( $arr [ 'mimetype' ])) : 'text/bbcode' );
2013-08-11 23:56:06 +00:00
if (( $arr [ 'mimetype' ] == 'application/x-php' ) && ( ! $allow_exec )) {
logger ( 'item_store: php mimetype but allow_exec is denied.' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'exec denied.' ;
return $ret ;
2013-08-11 23:56:06 +00:00
}
2014-08-21 23:46:24 +00:00
$arr [ 'title' ] = (( array_key_exists ( 'title' , $arr ) && strlen ( $arr [ 'title' ])) ? trim ( $arr [ 'title' ]) : '' );
$arr [ 'body' ] = (( array_key_exists ( 'body' , $arr ) && strlen ( $arr [ 'body' ])) ? trim ( $arr [ 'body' ]) : '' );
2013-08-02 02:18:05 +00:00
2014-09-03 12:09:43 +00:00
$arr [ 'diaspora_meta' ] = (( x ( $arr , 'diaspora_meta' )) ? $arr [ 'diaspora_meta' ] : '' );
2013-08-02 02:18:05 +00:00
$arr [ 'allow_cid' ] = (( x ( $arr , 'allow_cid' )) ? trim ( $arr [ 'allow_cid' ]) : '' );
$arr [ 'allow_gid' ] = (( x ( $arr , 'allow_gid' )) ? trim ( $arr [ 'allow_gid' ]) : '' );
$arr [ 'deny_cid' ] = (( x ( $arr , 'deny_cid' )) ? trim ( $arr [ 'deny_cid' ]) : '' );
$arr [ 'deny_gid' ] = (( x ( $arr , 'deny_gid' )) ? trim ( $arr [ 'deny_gid' ]) : '' );
$arr [ 'item_private' ] = (( x ( $arr , 'item_private' )) ? intval ( $arr [ 'item_private' ]) : 0 );
$arr [ 'item_flags' ] = (( x ( $arr , 'item_flags' )) ? intval ( $arr [ 'item_flags' ]) : 0 );
2013-09-02 08:38:17 +00:00
2013-10-03 04:04:48 +00:00
2013-08-02 01:50:36 +00:00
// only detect language if we have text content, and if the post is private but not yet
// obscured, make it so.
if ( ! ( $arr [ 'item_flags' ] & ITEM_OBSCURED )) {
2013-10-03 04:04:48 +00:00
2013-08-02 01:50:36 +00:00
$arr [ 'lang' ] = detect_language ( $arr [ 'body' ]);
2013-09-04 05:48:08 +00:00
// apply the input filter here - if it is obscured it has been filtered already
$arr [ 'body' ] = z_input_filter ( $arr [ 'uid' ], $arr [ 'body' ], $arr [ 'mimetype' ]);
2013-08-02 01:50:36 +00:00
2013-10-03 04:04:48 +00:00
if ( local_user () && ( ! $arr [ 'sig' ])) {
$channel = get_app () -> get_channel ();
if ( $channel [ 'channel_hash' ] === $arr [ 'author_xchan' ]) {
$arr [ 'sig' ] = base64url_encode ( rsa_sign ( $arr [ 'body' ], $channel [ 'channel_prvkey' ]));
$arr [ 'item_flags' ] |= ITEM_VERIFIED ;
}
}
2013-08-02 01:50:36 +00:00
$allowed_languages = get_pconfig ( $arr [ 'uid' ], 'system' , 'allowed_languages' );
2012-07-16 10:32:42 +00:00
2013-08-02 01:50:36 +00:00
if (( is_array ( $allowed_languages )) && ( $arr [ 'lang' ]) && ( ! array_key_exists ( $arr [ 'lang' ], $allowed_languages ))) {
$translate = array ( 'item' => $arr , 'from' => $arr [ 'lang' ], 'to' => $allowed_languages , 'translated' => false );
call_hooks ( 'item_translate' , $translate );
if (( ! $translate [ 'translated' ]) && ( intval ( get_pconfig ( $arr [ 'uid' ], 'system' , 'reject_disallowed_languages' )))) {
logger ( 'item_store: language ' . $arr [ 'lang' ] . ' not accepted for uid ' . $arr [ 'uid' ]);
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'language not accepted' ;
return $ret ;
2013-08-02 01:50:36 +00:00
}
$arr = $translate [ 'item' ];
2012-07-16 10:32:42 +00:00
}
2013-08-02 01:50:36 +00:00
if ( $arr [ 'item_private' ]) {
$key = get_config ( 'system' , 'pubkey' );
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_OBSCURED ;
if ( $arr [ 'title' ])
2013-11-20 23:20:12 +00:00
$arr [ 'title' ] = json_encode ( crypto_encapsulate ( $arr [ 'title' ], $key ));
2013-08-02 01:50:36 +00:00
if ( $arr [ 'body' ])
2013-11-20 23:20:12 +00:00
$arr [ 'body' ] = json_encode ( crypto_encapsulate ( $arr [ 'body' ], $key ));
2013-08-02 01:50:36 +00:00
}
2012-07-16 10:32:42 +00:00
}
2011-02-02 02:20:25 +00:00
2013-01-07 21:58:25 +00:00
if (( x ( $arr , 'object' )) && is_array ( $arr [ 'object' ])) {
activity_sanitise ( $arr [ 'object' ]);
$arr [ 'object' ] = json_encode ( $arr [ 'object' ]);
}
if (( x ( $arr , 'target' )) && is_array ( $arr [ 'target' ])) {
activity_sanitise ( $arr [ 'target' ]);
$arr [ 'target' ] = json_encode ( $arr [ 'target' ]);
}
2013-02-01 08:49:07 +00:00
if (( x ( $arr , 'attach' )) && is_array ( $arr [ 'attach' ])) {
activity_sanitise ( $arr [ 'attach' ]);
$arr [ 'attach' ] = json_encode ( $arr [ 'attach' ]);
}
2012-10-04 05:28:19 +00:00
$arr [ 'aid' ] = (( x ( $arr , 'aid' )) ? intval ( $arr [ 'aid' ]) : 0 );
2013-03-22 01:25:41 +00:00
$arr [ 'mid' ] = (( x ( $arr , 'mid' )) ? notags ( trim ( $arr [ 'mid' ])) : random_string ());
2012-10-04 05:28:19 +00:00
$arr [ 'author_xchan' ] = (( x ( $arr , 'author_xchan' )) ? notags ( trim ( $arr [ 'author_xchan' ])) : '' );
$arr [ 'owner_xchan' ] = (( x ( $arr , 'owner_xchan' )) ? notags ( trim ( $arr [ 'owner_xchan' ])) : '' );
2010-11-10 04:38:24 +00:00
$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 ());
2014-09-09 03:35:15 +00:00
$arr [ 'expires' ] = (( x ( $arr , 'expires' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'expires' ]) : NULL_DATE );
2013-11-18 03:22:24 +00:00
$arr [ 'commented' ] = (( x ( $arr , 'commented' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'commented' ]) : datetime_convert ());
2014-09-09 03:35:15 +00:00
$arr [ 'comments_closed' ] = (( x ( $arr , 'comments_closed' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'comments_closed' ]) : NULL_DATE );
2014-08-28 23:56:13 +00:00
2011-06-24 00:56:59 +00:00
$arr [ 'received' ] = datetime_convert ();
2010-11-10 04:38:24 +00:00
$arr [ 'changed' ] = datetime_convert ();
$arr [ 'location' ] = (( x ( $arr , 'location' )) ? notags ( trim ( $arr [ 'location' ])) : '' );
$arr [ 'coord' ] = (( x ( $arr , 'coord' )) ? notags ( trim ( $arr [ 'coord' ])) : '' );
2013-09-11 05:45:04 +00:00
$arr [ 'parent_mid' ] = (( x ( $arr , 'parent_mid' )) ? notags ( trim ( $arr [ 'parent_mid' ])) : '' );
2013-04-04 01:04:48 +00:00
$arr [ 'thr_parent' ] = (( x ( $arr , 'thr_parent' )) ? notags ( trim ( $arr [ 'thr_parent' ])) : $arr [ 'parent_mid' ]);
2010-11-10 04:38:24 +00:00
$arr [ 'verb' ] = (( x ( $arr , 'verb' )) ? notags ( trim ( $arr [ 'verb' ])) : '' );
2012-10-06 08:17:25 +00:00
$arr [ 'obj_type' ] = (( x ( $arr , 'obj_type' )) ? notags ( trim ( $arr [ 'obj_type' ])) : '' );
2010-11-10 04:38:24 +00:00
$arr [ 'object' ] = (( x ( $arr , 'object' )) ? trim ( $arr [ 'object' ]) : '' );
2012-10-06 08:17:25 +00:00
$arr [ 'tgt_type' ] = (( x ( $arr , 'tgt_type' )) ? notags ( trim ( $arr [ 'tgt_type' ])) : '' );
2010-11-10 04:38:24 +00:00
$arr [ 'target' ] = (( x ( $arr , 'target' )) ? trim ( $arr [ 'target' ]) : '' );
2011-02-16 10:07:11 +00:00
$arr [ 'plink' ] = (( x ( $arr , 'plink' )) ? notags ( trim ( $arr [ 'plink' ])) : '' );
2011-04-07 04:59:07 +00:00
$arr [ 'attach' ] = (( x ( $arr , 'attach' )) ? notags ( trim ( $arr [ 'attach' ])) : '' );
2011-06-21 02:08:40 +00:00
$arr [ 'app' ] = (( x ( $arr , 'app' )) ? notags ( trim ( $arr [ 'app' ])) : '' );
2012-10-07 23:39:29 +00:00
$arr [ 'item_restrict' ] = (( x ( $arr , 'item_restrict' )) ? intval ( $arr [ 'item_restrict' ]) : 0 );
2013-06-17 03:44:29 +00:00
2014-08-07 00:36:07 +00:00
$arr [ 'public_policy' ] = (( x ( $arr , 'public_policy' )) ? notags ( trim ( $arr [ 'public_policy' ])) : '' );
2013-06-17 03:44:29 +00:00
$arr [ 'comment_policy' ] = (( x ( $arr , 'comment_policy' )) ? notags ( trim ( $arr [ 'comment_policy' ])) : 'contacts' );
2012-10-06 08:17:25 +00:00
2012-11-30 04:46:45 +00:00
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_UNSEEN ;
2012-12-16 10:18:26 +00:00
2013-06-17 03:44:29 +00:00
if ( $arr [ 'comment_policy' ] == 'none' )
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_NOCOMMENT ;
2013-05-24 00:24:15 +00:00
// handle time travelers
// Allow a bit of fudge in case somebody just has a slightly slow/fast clock
2013-05-30 04:11:30 +00:00
$d1 = new DateTime ( 'now +10 minutes' , new DateTimeZone ( 'UTC' ));
$d2 = new DateTime ( $arr [ 'created' ] . '+00:00' );
2013-05-24 00:24:15 +00:00
if ( $d2 > $d1 )
$arr [ 'item_restrict' ] = $arr [ 'item_restrict' ] | ITEM_DELAYED_PUBLISH ;
2013-03-22 01:25:41 +00:00
$arr [ 'llink' ] = z_root () . '/display/' . $arr [ 'mid' ];
2012-12-16 10:18:26 +00:00
2014-01-09 23:45:17 +00:00
if ( ! $arr [ 'plink' ])
$arr [ 'plink' ] = $arr [ 'llink' ];
2012-12-16 10:18:26 +00:00
2013-03-22 01:25:41 +00:00
if ( $arr [ 'parent_mid' ] === $arr [ 'mid' ]) {
2010-11-12 04:32:20 +00:00
$parent_id = 0 ;
2012-02-28 12:56:16 +00:00
$parent_deleted = 0 ;
2010-11-12 04:32:20 +00:00
$allow_cid = $arr [ 'allow_cid' ];
$allow_gid = $arr [ 'allow_gid' ];
$deny_cid = $arr [ 'deny_cid' ];
$deny_gid = $arr [ 'deny_gid' ];
2014-08-09 22:21:15 +00:00
$public_policy = $arr [ 'public_policy' ];
2014-08-28 23:56:13 +00:00
$comments_closed = $arr [ 'comments_closed' ];
2012-11-27 07:52:16 +00:00
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_THREAD_TOP ;
2010-11-12 04:32:20 +00:00
}
else {
// find the parent and snarf the item id and ACL's
2011-03-08 22:40:33 +00:00
// and anything else we need to inherit
2010-11-12 04:32:20 +00:00
2013-03-22 01:25:41 +00:00
$r = q ( " SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d ORDER BY `id` ASC LIMIT 1 " ,
dbesc ( $arr [ 'parent_mid' ]),
2010-11-12 04:32:20 +00:00
intval ( $arr [ 'uid' ])
);
2013-07-22 05:39:21 +00:00
if ( $r ) {
2010-12-05 07:16:16 +00:00
2014-08-28 23:56:13 +00:00
if ( comments_are_now_closed ( $r [ 0 ])) {
logger ( 'item_store: comments closed' );
$ret [ 'message' ] = 'Comments closed.' ;
2014-08-30 00:31:40 +00:00
return $ret ;
2014-08-28 23:56:13 +00:00
}
2010-12-05 07:16:16 +00:00
// is the new message multi-level threaded?
// even though we don't support it now, preserve the info
// and re-attach to the conversation parent.
2013-03-22 01:25:41 +00:00
if ( $r [ 0 ][ 'mid' ] != $r [ 0 ][ 'parent_mid' ]) {
$arr [ 'parent_mid' ] = $r [ 0 ][ 'parent_mid' ];
$z = q ( " SELECT * FROM `item` WHERE `mid` = '%s' AND `parent_mid` = '%s' AND `uid` = %d
2011-10-12 09:21:18 +00:00
ORDER BY `id` ASC LIMIT 1 " ,
2013-03-22 01:25:41 +00:00
dbesc ( $r [ 0 ][ 'parent_mid' ]),
dbesc ( $r [ 0 ][ 'parent_mid' ]),
2011-08-09 02:10:36 +00:00
intval ( $arr [ 'uid' ])
);
if ( $z && count ( $z ))
$r = $z ;
2010-12-05 07:16:16 +00:00
}
2014-08-28 23:56:13 +00:00
$parent_id = $r [ 0 ][ 'id' ];
$parent_deleted = $r [ 0 ][ 'item_restrict' ] & ITEM_DELETED ;
$allow_cid = $r [ 0 ][ 'allow_cid' ];
$allow_gid = $r [ 0 ][ 'allow_gid' ];
$deny_cid = $r [ 0 ][ 'deny_cid' ];
$deny_gid = $r [ 0 ][ 'deny_gid' ];
$public_policy = $r [ 0 ][ 'public_policy' ];
$comments_closed = $r [ 0 ][ 'comments_closed' ];
2012-10-06 08:17:25 +00:00
2012-10-07 23:39:29 +00:00
if ( $r [ 0 ][ 'item_flags' ] & ITEM_WALL )
2012-10-06 08:17:25 +00:00
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_WALL ;
2012-06-11 12:28:08 +00:00
2013-10-14 01:36:28 +00:00
// An uplinked comment might arrive with a downstream owner.
// Fix it.
if ( $r [ 0 ][ 'owner_xchan' ] !== $arr [ 'owner_xchan' ]) {
$arr [ 'owner_xchan' ] = $r [ 0 ][ 'owner_xchan' ];
$uplinked_comment = true ;
}
2012-06-11 12:28:08 +00:00
// if the parent is private, force privacy for the entire conversation
2012-10-08 01:44:06 +00:00
if ( $r [ 0 ][ 'item_private' ])
$arr [ 'item_private' ] = $r [ 0 ][ 'item_private' ];
2012-06-11 12:28:08 +00:00
2012-06-19 00:19:56 +00:00
// Edge case. We host a public forum that was originally posted to privately.
// The original author commented, but as this is a comment, the permissions
// weren't fixed up so it will still show the comment as private unless we fix it here.
2012-10-08 01:44:06 +00:00
if (( intval ( $r [ 0 ][ 'item_flags' ]) & ITEM_UPLINK ) && ( ! $r [ 0 ][ 'item_private' ]))
$arr [ 'item_private' ] = 0 ;
2010-11-12 04:32:20 +00:00
}
else {
2013-03-28 02:02:01 +00:00
logger ( 'item_store: item parent was not found - ignoring item' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'parent not found.' ;
return $ret ;
2010-11-12 04:32:20 +00:00
}
}
2010-07-19 03:49:10 +00:00
2012-10-06 08:17:25 +00:00
if ( $parent_deleted )
$arr [ 'item_restrict' ] = $arr [ 'item_restrict' ] | ITEM_DELETED ;
2013-03-22 01:25:41 +00:00
$r = q ( " SELECT `id` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1 " ,
dbesc ( $arr [ 'mid' ]),
2011-10-12 09:21:18 +00:00
intval ( $arr [ 'uid' ])
2011-10-03 13:04:17 +00:00
);
2012-11-28 01:09:01 +00:00
if ( $r ) {
2013-09-11 04:10:56 +00:00
logger ( 'item_store: duplicate item ignored. ' . print_r ( $arr , true ));
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'duplicate post.' ;
return $ret ;
2011-10-03 13:04:17 +00:00
}
2011-08-08 00:29:26 +00:00
2014-04-26 04:12:43 +00:00
call_hooks ( 'item_store' , $arr );
// This hook remains for backward compatibility.
2010-12-22 22:16:22 +00:00
call_hooks ( 'post_remote' , $arr );
2012-01-31 04:49:54 +00:00
if ( x ( $arr , 'cancel' )) {
logger ( 'item_store: post cancelled by plugin.' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'cancelled.' ;
return $ret ;
2012-01-31 04:49:54 +00:00
}
2012-07-11 11:29:47 +00:00
// pull out all the taxonomy stuff for separate storage
$terms = null ;
2012-11-27 05:20:16 +00:00
if ( array_key_exists ( 'term' , $arr )) {
2012-07-11 11:29:47 +00:00
$terms = $arr [ 'term' ];
unset ( $arr [ 'term' ]);
}
2010-11-04 02:47:07 +00:00
logger ( 'item_store: ' . print_r ( $arr , true ), LOGGER_DATA );
2013-08-18 07:04:38 +00:00
dbesc_array ( $arr );
2010-11-09 23:11:47 +00:00
$r = dbq ( " INSERT INTO `item` (` "
2010-07-19 03:49:10 +00:00
. implode ( " `, ` " , array_keys ( $arr ))
. " `) VALUES (' "
. implode ( " ', ' " , array_values ( $arr ))
. " ') " );
2010-11-12 04:32:20 +00:00
// find the item we just created
2010-07-19 03:49:10 +00:00
2013-09-11 06:25:56 +00:00
$r = q ( " SELECT * FROM `item` WHERE `mid` = '%s' AND `uid` = %d ORDER BY `id` ASC " ,
2013-03-22 01:25:41 +00:00
$arr [ 'mid' ], // already dbesc'd
2010-07-19 03:49:10 +00:00
intval ( $arr [ 'uid' ])
);
2011-05-30 05:50:36 +00:00
2013-09-11 06:25:56 +00:00
2012-10-08 07:23:43 +00:00
if ( $r && count ( $r )) {
2010-07-19 03:49:10 +00:00
$current_post = $r [ 0 ][ 'id' ];
2013-09-11 04:10:56 +00:00
$arr = $r [ 0 ]; // This will gives us a fresh copy of what's now in the DB and undo the db escaping, which really messes up the notifications
2012-10-08 07:23:43 +00:00
logger ( 'item_store: created item ' . $current_post , LOGGER_DEBUG );
2010-11-04 02:47:07 +00:00
}
2010-11-12 04:32:20 +00:00
else {
2013-09-11 03:14:12 +00:00
logger ( 'item_store: could not locate stored item' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'unable to retrieve.' ;
return $ret ;
2010-09-09 03:14:17 +00:00
}
2011-10-12 09:21:18 +00:00
if ( count ( $r ) > 1 ) {
logger ( 'item_store: duplicated post occurred. Removing duplicates.' );
2013-03-22 01:25:41 +00:00
q ( " DELETE FROM `item` WHERE `mid` = '%s' AND `uid` = %d AND `id` != %d " ,
$arr [ 'mid' ],
2011-10-12 09:21:18 +00:00
intval ( $arr [ 'uid' ]),
intval ( $current_post )
);
}
2010-07-19 03:49:10 +00:00
2013-03-22 01:25:41 +00:00
if (( ! $parent_id ) || ( $arr [ 'parent_mid' ] === $arr [ 'mid' ]))
2010-11-12 04:32:20 +00:00
$parent_id = $current_post ;
2011-02-04 21:37:04 +00:00
2014-08-07 02:24:46 +00:00
if ( strlen ( $allow_cid ) || strlen ( $allow_gid ) || strlen ( $deny_cid ) || strlen ( $deny_gid ) || strlen ( $public_policy ))
2010-12-08 04:47:53 +00:00
$private = 1 ;
else
2013-07-29 04:04:03 +00:00
$private = $arr [ 'item_private' ];
2010-12-08 04:47:53 +00:00
2010-11-12 04:32:20 +00:00
// Set parent id - and also make sure to inherit the parent's ACL's.
2010-09-29 05:32:48 +00:00
2013-05-28 08:40:27 +00:00
$r = q ( " UPDATE item SET parent = %d, allow_cid = '%s', allow_gid = '%s',
2014-08-28 23:56:13 +00:00
deny_cid = '%s' , deny_gid = '%s' , public_policy = '%s' , item_private = % d , comments_closed = '%s'
WHERE id = % d LIMIT 1 " ,
2010-07-19 03:49:10 +00:00
intval ( $parent_id ),
2010-09-29 05:32:48 +00:00
dbesc ( $allow_cid ),
dbesc ( $allow_gid ),
dbesc ( $deny_cid ),
dbesc ( $deny_gid ),
2014-08-07 02:24:46 +00:00
dbesc ( $public_policy ),
2010-12-08 04:47:53 +00:00
intval ( $private ),
2014-08-28 23:56:13 +00:00
dbesc ( $comments_closed ),
2010-07-19 03:49:10 +00:00
intval ( $current_post )
);
2013-09-11 04:10:56 +00:00
// These are probably redundant now that we've queried the just stored post
2012-10-08 07:23:43 +00:00
$arr [ 'id' ] = $current_post ;
$arr [ 'parent' ] = $parent_id ;
2012-07-11 11:29:47 +00:00
$arr [ 'allow_cid' ] = $allow_cid ;
$arr [ 'allow_gid' ] = $allow_gid ;
2012-10-08 07:23:43 +00:00
$arr [ 'deny_cid' ] = $deny_cid ;
$arr [ 'deny_gid' ] = $deny_gid ;
2014-08-07 02:24:46 +00:00
$arr [ 'public_policy' ] = $public_policy ;
2013-07-29 04:04:03 +00:00
$arr [ 'item_private' ] = $private ;
2014-08-28 23:56:13 +00:00
$arr [ 'comments_closed' ] = $comments_closed ;
2012-10-08 07:23:43 +00:00
// Store taxonomy
2013-02-11 08:20:14 +00:00
2012-07-11 11:29:47 +00:00
if (( $terms ) && ( is_array ( $terms ))) {
foreach ( $terms as $t ) {
q ( " insert into term (uid,oid,otype,type,term,url)
values ( % d , % d , % d , % d , '%s' , '%s' ) " ,
intval ( $arr [ 'uid' ]),
intval ( $current_post ),
2013-02-11 08:20:14 +00:00
intval ( TERM_OBJ_POST ),
2012-07-11 11:29:47 +00:00
intval ( $t [ 'type' ]),
dbesc ( $t [ 'term' ]),
dbesc ( $t [ 'url' ])
);
}
$arr [ 'term' ] = $terms ;
}
2012-06-12 05:09:50 +00:00
call_hooks ( 'post_remote_end' , $arr );
2011-09-19 02:04:11 +00:00
// update the commented timestamp on the parent
2011-09-16 13:49:24 +00:00
2014-08-29 00:25:00 +00:00
$z = q ( " select max(created) as commented from item where parent_mid = '%s' and uid = %d and not ( item_restrict & %d ) " ,
2013-11-18 03:22:24 +00:00
dbesc ( $arr [ 'parent_mid' ]),
2014-08-29 00:25:00 +00:00
intval ( $arr [ 'uid' ]),
intval ( ITEM_DELAYED_PUBLISH )
2013-11-18 03:22:24 +00:00
);
2013-11-18 04:09:40 +00:00
q ( " UPDATE item set commented = '%s', changed = '%s' WHERE id = %d LIMIT 1 " ,
dbesc (( $z ) ? $z [ 0 ][ 'commented' ] : ( datetime_convert ())),
dbesc ( datetime_convert ()),
2011-09-16 13:49:24 +00:00
intval ( $parent_id )
);
2013-02-07 04:29:17 +00:00
send_status_notifications ( $current_post , $arr );
2012-02-10 05:18:50 +00:00
tag_deliver ( $arr [ 'uid' ], $current_post );
2013-09-11 02:06:06 +00:00
$ret [ 'success' ] = true ;
$ret [ 'item_id' ] = $current_post ;
2011-11-16 04:30:34 +00:00
2013-09-11 02:06:06 +00:00
return $ret ;
2010-07-19 03:49:10 +00:00
}
2010-09-26 23:30:21 +00:00
2013-02-07 04:29:17 +00:00
2013-03-01 02:20:42 +00:00
2013-08-11 23:56:06 +00:00
function item_store_update ( $arr , $allow_exec = false ) {
2013-03-01 02:20:42 +00:00
2013-11-29 02:10:04 +00:00
$d = array ( 'item' => $arr , 'allow_exec' => $allow_exec );
call_hooks ( 'item_store_update' , $d );
$arr = $d [ 'item' ];
$allow_exec = $d [ 'allow_exec' ];
2014-03-05 03:57:54 +00:00
$ret = array ( 'success' => false , 'item_id' => 0 );
2013-03-01 02:20:42 +00:00
if ( ! intval ( $arr [ 'uid' ])) {
logger ( 'item_store_update: no uid' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'no uid.' ;
return $ret ;
2013-03-01 02:20:42 +00:00
}
if ( ! intval ( $arr [ 'id' ])) {
logger ( 'item_store_update: no id' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'no id.' ;
return $ret ;
2013-03-01 02:20:42 +00:00
}
$orig_post_id = $arr [ 'id' ];
$uid = $arr [ 'uid' ];
2013-10-04 11:47:41 +00:00
$orig = q ( " select * from item where id = %d and uid = %d limit 1 " ,
intval ( $orig_post_id ),
intval ( $uid )
);
if ( ! $orig ) {
logger ( 'item_store_update: original post not found: ' . $orig_post_id );
$ret [ 'message' ] = 'no original' ;
return $ret ;
}
2013-10-20 06:38:07 +00:00
// override the unseen flag with the original
if ( $arr [ 'item_flags' ] & ITEM_UNSEEN )
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] ^ ITEM_UNSEEN ;
2013-10-04 11:47:41 +00:00
if ( $orig [ 0 ][ 'item_flags' ] & ITEM_VERIFIED )
$orig [ 0 ][ 'item_flags' ] = $orig [ 0 ][ 'item_flags' ] ^ ITEM_VERIFIED ;
2014-06-16 01:58:02 +00:00
if ( $orig [ 0 ][ 'item_flags' ] & ITEM_OBSCURED )
$orig [ 0 ][ 'item_flags' ] = $orig [ 0 ][ 'item_flags' ] ^ ITEM_OBSCURED ;
2013-10-04 11:47:41 +00:00
$arr [ 'item_flags' ] = intval ( $arr [ 'item_flags' ]) | $orig [ 0 ][ 'item_flags' ];
$arr [ 'item_restrict' ] = intval ( $arr [ 'item_restrict' ]) | $orig [ 0 ][ 'item_restrict' ];
2013-10-14 03:09:11 +00:00
2013-10-04 11:47:41 +00:00
if ( array_key_exists ( 'edit' , $arr ))
unset ( $arr [ 'edit' ]);
2013-08-11 23:56:06 +00:00
$arr [ 'mimetype' ] = (( x ( $arr , 'mimetype' )) ? notags ( trim ( $arr [ 'mimetype' ])) : 'text/bbcode' );
if (( $arr [ 'mimetype' ] == 'application/x-php' ) && ( ! $allow_exec )) {
logger ( 'item_store: php mimetype but allow_exec is denied.' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'exec denied.' ;
return $ret ;
2013-08-11 23:56:06 +00:00
}
2013-10-03 04:04:48 +00:00
if ( ! ( $arr [ 'item_flags' ] & ITEM_OBSCURED )) {
2013-08-11 23:56:06 +00:00
2013-10-03 04:04:48 +00:00
$arr [ 'lang' ] = detect_language ( $arr [ 'body' ]);
// apply the input filter here - if it is obscured it has been filtered already
$arr [ 'body' ] = z_input_filter ( $arr [ 'uid' ], $arr [ 'body' ], $arr [ 'mimetype' ]);
2013-03-01 02:20:42 +00:00
2013-10-03 04:04:48 +00:00
if ( local_user () && ( ! $arr [ 'sig' ])) {
$channel = get_app () -> get_channel ();
if ( $channel [ 'channel_hash' ] === $arr [ 'author_xchan' ]) {
$arr [ 'sig' ] = base64url_encode ( rsa_sign ( $arr [ 'body' ], $channel [ 'channel_prvkey' ]));
$arr [ 'item_flags' ] |= ITEM_VERIFIED ;
}
}
2013-03-01 02:20:42 +00:00
2013-10-03 04:04:48 +00:00
$allowed_languages = get_pconfig ( $arr [ 'uid' ], 'system' , 'allowed_languages' );
if (( is_array ( $allowed_languages )) && ( $arr [ 'lang' ]) && ( ! array_key_exists ( $arr [ 'lang' ], $allowed_languages ))) {
$translate = array ( 'item' => $arr , 'from' => $arr [ 'lang' ], 'to' => $allowed_languages , 'translated' => false );
call_hooks ( 'item_translate' , $translate );
if (( ! $translate [ 'translated' ]) && ( intval ( get_pconfig ( $arr [ 'uid' ], 'system' , 'reject_disallowed_languages' )))) {
logger ( 'item_store: language ' . $arr [ 'lang' ] . ' not accepted for uid ' . $arr [ 'uid' ]);
$ret [ 'message' ] = 'language not accepted' ;
return $ret ;
}
$arr = $translate [ 'item' ];
2013-08-11 23:56:06 +00:00
}
2013-10-03 04:04:48 +00:00
if ( $arr [ 'item_private' ]) {
$key = get_config ( 'system' , 'pubkey' );
$arr [ 'item_flags' ] = $arr [ 'item_flags' ] | ITEM_OBSCURED ;
if ( $arr [ 'title' ])
2013-11-20 23:20:12 +00:00
$arr [ 'title' ] = json_encode ( crypto_encapsulate ( $arr [ 'title' ], $key ));
2013-10-03 04:04:48 +00:00
if ( $arr [ 'body' ])
2013-11-20 23:20:12 +00:00
$arr [ 'body' ] = json_encode ( crypto_encapsulate ( $arr [ 'body' ], $key ));
2013-10-03 04:04:48 +00:00
}
2013-03-01 02:20:42 +00:00
2013-10-03 04:04:48 +00:00
}
2013-08-11 23:56:06 +00:00
2013-10-03 04:04:48 +00:00
if (( x ( $arr , 'object' )) && is_array ( $arr [ 'object' ])) {
activity_sanitise ( $arr [ 'object' ]);
$arr [ 'object' ] = json_encode ( $arr [ 'object' ]);
}
if (( x ( $arr , 'target' )) && is_array ( $arr [ 'target' ])) {
activity_sanitise ( $arr [ 'target' ]);
$arr [ 'target' ] = json_encode ( $arr [ 'target' ]);
}
if (( x ( $arr , 'attach' )) && is_array ( $arr [ 'attach' ])) {
activity_sanitise ( $arr [ 'attach' ]);
$arr [ 'attach' ] = json_encode ( $arr [ 'attach' ]);
2013-03-01 02:20:42 +00:00
}
2013-10-03 04:04:48 +00:00
2013-11-21 00:20:32 +00:00
unset ( $arr [ 'id' ]);
unset ( $arr [ 'uid' ]);
2013-03-01 02:20:42 +00:00
unset ( $arr [ 'aid' ]);
2013-03-22 01:25:41 +00:00
unset ( $arr [ 'mid' ]);
2013-03-01 02:20:42 +00:00
unset ( $arr [ 'parent' ]);
2013-03-22 01:25:41 +00:00
unset ( $arr [ 'parent_mid' ]);
2013-03-01 02:20:42 +00:00
unset ( $arr [ 'created' ]);
unset ( $arr [ 'author_xchan' ]);
unset ( $arr [ 'owner_xchan' ]);
unset ( $arr [ 'thr_parent' ]);
unset ( $arr [ 'llink' ]);
$arr [ 'edited' ] = (( x ( $arr , 'edited' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'edited' ]) : datetime_convert ());
2014-06-14 23:35:38 +00:00
$arr [ 'expires' ] = (( x ( $arr , 'expires' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'expires' ]) : $orig [ 0 ][ 'expires' ]);
2014-08-28 23:56:13 +00:00
2014-09-09 03:35:15 +00:00
if ( array_key_exists ( 'comments_closed' , $arr ) && $arr [ 'comments_closed' ] != NULL_DATE )
2014-08-28 23:56:13 +00:00
$arr [ 'comments_closed' ] = datetime_convert ( 'UTC' , 'UTC' , $arr [ 'comments_closed' ]);
else
$arr [ 'comments_closed' ] = $orig [ 0 ][ 'comments_closed' ];
2013-10-20 06:38:07 +00:00
$arr [ 'commented' ] = $orig [ 0 ][ 'commented' ];
2013-03-01 02:20:42 +00:00
$arr [ 'received' ] = datetime_convert ();
$arr [ 'changed' ] = datetime_convert ();
2014-09-03 12:09:43 +00:00
$arr [ 'diaspora_meta' ] = (( x ( $arr , 'diaspora_meta' )) ? $arr [ 'diaspora_meta' ] : $orig [ 0 ][ 'diaspora_meta' ]);
2013-10-04 11:47:41 +00:00
$arr [ 'location' ] = (( x ( $arr , 'location' )) ? notags ( trim ( $arr [ 'location' ])) : $orig [ 0 ][ 'location' ]);
$arr [ 'coord' ] = (( x ( $arr , 'coord' )) ? notags ( trim ( $arr [ 'coord' ])) : $orig [ 0 ][ 'coord' ]);
$arr [ 'verb' ] = (( x ( $arr , 'verb' )) ? notags ( trim ( $arr [ 'verb' ])) : $orig [ 0 ][ 'verb' ]);
$arr [ 'obj_type' ] = (( x ( $arr , 'obj_type' )) ? notags ( trim ( $arr [ 'obj_type' ])) : $orig [ 0 ][ 'obj_type' ]);
$arr [ 'object' ] = (( x ( $arr , 'object' )) ? trim ( $arr [ 'object' ]) : $orig [ 0 ][ 'object' ]);
$arr [ 'tgt_type' ] = (( x ( $arr , 'tgt_type' )) ? notags ( trim ( $arr [ 'tgt_type' ])) : $orig [ 0 ][ 'tgt_type' ]);
$arr [ 'target' ] = (( x ( $arr , 'target' )) ? trim ( $arr [ 'target' ]) : $orig [ 0 ][ 'target' ]);
2013-03-01 02:20:42 +00:00
$arr [ 'plink' ] = (( x ( $arr , 'plink' )) ? notags ( trim ( $arr [ 'plink' ])) : $orig [ 0 ][ 'plink' ]);
2014-06-14 23:35:38 +00:00
$arr [ 'allow_cid' ] = (( array_key_exists ( 'allow_cid' , $arr )) ? trim ( $arr [ 'allow_cid' ]) : $orig [ 0 ][ 'allow_cid' ]);
$arr [ 'allow_gid' ] = (( array_key_exists ( 'allow_gid' , $arr )) ? trim ( $arr [ 'allow_gid' ]) : $orig [ 0 ][ 'allow_gid' ]);
$arr [ 'deny_cid' ] = (( array_key_exists ( 'deny_cid' , $arr )) ? trim ( $arr [ 'deny_cid' ]) : $orig [ 0 ][ 'deny_cid' ]);
$arr [ 'deny_gid' ] = (( array_key_exists ( 'deny_gid' , $arr )) ? trim ( $arr [ 'deny_gid' ]) : $orig [ 0 ][ 'deny_gid' ]);
$arr [ 'item_private' ] = (( array_key_exists ( 'item_private' , $arr )) ? intval ( $arr [ 'item_private' ]) : $orig [ 0 ][ 'item_private' ]);
2014-08-21 23:46:24 +00:00
$arr [ 'title' ] = (( array_key_exists ( 'title' , $arr ) && strlen ( $arr [ 'title' ])) ? trim ( $arr [ 'title' ]) : '' );
$arr [ 'body' ] = (( array_key_exists ( 'body' , $arr ) && strlen ( $arr [ 'body' ])) ? trim ( $arr [ 'body' ]) : '' );
2013-10-04 11:47:41 +00:00
$arr [ 'attach' ] = (( x ( $arr , 'attach' )) ? notags ( trim ( $arr [ 'attach' ])) : $orig [ 0 ][ 'attach' ]);
$arr [ 'app' ] = (( x ( $arr , 'app' )) ? notags ( trim ( $arr [ 'app' ])) : $orig [ 0 ][ 'app' ]);
// $arr['item_restrict'] = ((x($arr,'item_restrict')) ? intval($arr['item_restrict']) : $orig[0]['item_restrict'] );
// $arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : $orig[0]['item_flags'] );
2013-03-01 02:20:42 +00:00
2013-10-04 11:47:41 +00:00
$arr [ 'sig' ] = (( x ( $arr , 'sig' )) ? $arr [ 'sig' ] : '' );
2014-04-24 02:05:48 +00:00
$arr [ 'layout_mid' ] = (( array_key_exists ( 'layout_mid' , $arr )) ? dbesc ( $arr [ 'layout_mid' ]) : $orig [ 0 ][ 'layout_mid' ] );
2013-03-01 02:20:42 +00:00
2014-08-07 00:36:07 +00:00
$arr [ 'public_policy' ] = (( x ( $arr , 'public_policy' )) ? notags ( trim ( $arr [ 'public_policy' ])) : $orig [ 0 ][ 'public_policy' ] );
$arr [ 'comment_policy' ] = (( x ( $arr , 'comment_policy' )) ? notags ( trim ( $arr [ 'comment_policy' ])) : $orig [ 0 ][ 'comment_policy' ] );
2013-03-01 02:20:42 +00:00
call_hooks ( 'post_remote_update' , $arr );
if ( x ( $arr , 'cancel' )) {
logger ( 'item_store_update: post cancelled by plugin.' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'cancelled.' ;
return $ret ;
2013-03-01 02:20:42 +00:00
}
// pull out all the taxonomy stuff for separate storage
$terms = null ;
if ( array_key_exists ( 'term' , $arr )) {
$terms = $arr [ 'term' ];
unset ( $arr [ 'term' ]);
}
dbesc_array ( $arr );
logger ( 'item_store_update: ' . print_r ( $arr , true ), LOGGER_DATA );
$str = '' ;
foreach ( $arr as $k => $v ) {
if ( $str )
$str .= " , " ;
$str .= " ` " . $k . " ` = ' " . $v . " ' " ;
}
$r = dbq ( " update `item` set " . $str . " where id = " . $orig_post_id . " limit 1 " );
if ( $r )
logger ( 'item_store_update: updated item ' . $orig_post_id , LOGGER_DEBUG );
else {
logger ( 'item_store_update: could not update item' );
2013-09-11 02:06:06 +00:00
$ret [ 'message' ] = 'DB update failed.' ;
return $ret ;
2013-03-01 02:20:42 +00:00
}
$r = q ( " delete from term where oid = %d and otype = %d " ,
intval ( $orig_post_id ),
intval ( TERM_OBJ_POST )
);
if (( $terms ) && ( is_array ( $terms ))) {
foreach ( $terms as $t ) {
q ( " insert into term (uid,oid,otype,type,term,url)
values ( % d , % d , % d , % d , '%s' , '%s' ) " ,
intval ( $uid ),
intval ( $orig_post_id ),
intval ( TERM_OBJ_POST ),
intval ( $t [ 'type' ]),
dbesc ( $t [ 'term' ]),
dbesc ( $t [ 'url' ])
);
}
$arr [ 'term' ] = $terms ;
}
call_hooks ( 'post_remote_update_end' , $arr );
send_status_notifications ( $orig_post_id , $arr );
tag_deliver ( $uid , $orig_post_id );
2013-09-11 02:06:06 +00:00
$ret [ 'success' ] = true ;
$ret [ 'item_id' ] = $orig_post_id ;
2013-03-01 02:20:42 +00:00
2013-09-11 02:06:06 +00:00
return $ret ;
2013-03-01 02:20:42 +00:00
}
2014-08-30 00:31:40 +00:00
function store_diaspora_comment_sig ( $datarray , $channel , $parent_item , $post_id ) {
// We won't be able to sign Diaspora comments for authenticated visitors
// - we don't have their private key
// since Diaspora doesn't handle edits we can only do this for the original text and not update it.
$enabled = intval ( get_config ( 'system' , 'diaspora_enabled' ));
if ( ! $enabled ) {
logger ( 'mod_item: diaspora support disabled, not storing comment signature' , LOGGER_DEBUG );
return ;
}
require_once ( 'include/bb2diaspora.php' );
2014-09-19 09:22:24 +00:00
$signed_body = bb2diaspora_itembody ( $datarray );
2014-08-30 00:31:40 +00:00
2014-09-19 09:22:24 +00:00
logger ( 'mod_item: storing diaspora comment signature' , LOGGER_DEBUG );
2014-08-30 00:31:40 +00:00
$diaspora_handle = $channel [ 'channel_address' ] . '@' . get_app () -> get_hostname ();
$signed_text = $datarray [ 'mid' ] . ';' . $parent_item [ 'mid' ] . ';' . $signed_body . ';' . $diaspora_handle ;
if ( $uprvkey !== false )
$authorsig = base64_encode ( rsa_sign ( $signed_text , $channel [ 'channel_prvkey' ], 'sha256' ));
else
$authorsig = '' ;
2014-09-03 12:09:43 +00:00
$x = array ( 'signer' => $diaspora_handle , 'body' => $signed_body , 'signed_text' => $signed_text , 'signature' => base64_encode ( $authorsig ));
2014-09-11 02:02:00 +00:00
$key = get_config ( 'system' , 'pubkey' );
$y = crypto_encapsulate ( json_encode ( $x ), $key );
2014-09-03 12:09:43 +00:00
$r = q ( " update item set diaspora_meta = '%s' where id = %d limit 1 " ,
2014-09-11 02:02:00 +00:00
dbesc ( json_encode ( $y )),
2014-09-03 12:09:43 +00:00
intval ( $post_id )
);
2014-08-30 00:31:40 +00:00
$r = q ( " insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') " ,
intval ( $post_id ),
dbesc ( $signed_text ),
dbesc ( base64_encode ( $authorsig )),
dbesc ( $diaspora_handle )
);
if ( ! $r )
logger ( 'store_diaspora_comment_sig: DB write failed' );
return ;
}
2013-03-01 02:20:42 +00:00
2013-02-07 04:29:17 +00:00
function send_status_notifications ( $post_id , $item ) {
$notify = false ;
$parent = 0 ;
$r = q ( " select channel_hash from channel where channel_id = %d limit 1 " ,
intval ( $item [ 'uid' ])
);
if ( ! $r )
return ;
// my own post - no notification needed
if ( $item [ 'author_xchan' ] === $r [ 0 ][ 'channel_hash' ])
return ;
// I'm the owner - notify me
if ( $item [ 'owner_hash' ] === $r [ 0 ][ 'channel_hash' ])
$notify = true ;
// Was I involved in this conversation?
2013-03-22 01:25:41 +00:00
$x = q ( " select * from item where parent_mid = '%s' and uid = %d " ,
dbesc ( $item [ 'parent_mid' ]),
2013-02-07 04:29:17 +00:00
intval ( $item [ 'uid' ])
);
if ( $x ) {
foreach ( $x as $xx ) {
if ( $xx [ 'author_xchan' ] === $r [ 0 ][ 'channel_hash' ]) {
$notify = true ;
2013-02-15 04:17:30 +00:00
}
if ( $xx [ 'id' ] == $xx [ 'parent' ]) {
$parent = $xx [ 'parent' ];
2013-02-07 04:29:17 +00:00
}
}
}
2014-02-05 23:01:53 +00:00
$link = get_app () -> get_baseurl () . '/display/' . $item [ 'mid' ];
2014-02-06 21:32:29 +00:00
$y = q ( " select id from notify where link = '%s' and uid = %d limit 1 " ,
2014-02-05 23:01:53 +00:00
dbesc ( $link ),
intval ( $item [ 'uid' ])
);
2014-02-06 21:32:29 +00:00
if ( $y )
2014-02-05 23:01:53 +00:00
$notify = false ;
2013-02-07 04:29:17 +00:00
if ( ! $notify )
return ;
require_once ( 'include/enotify.php' );
notification ( array (
'type' => NOTIFY_COMMENT ,
'from_xchan' => $item [ 'author_xchan' ],
'to_xchan' => $r [ 0 ][ 'channel_hash' ],
'item' => $item ,
2014-02-05 23:01:53 +00:00
'link' => $link ,
2013-02-07 04:29:17 +00:00
'verb' => ACTIVITY_POST ,
'otype' => 'item' ,
'parent' => $parent ,
2013-03-22 01:25:41 +00:00
'parent_mid' => $item [ 'parent_mid' ]
2013-02-07 04:29:17 +00:00
));
return ;
}
2010-09-26 23:30:21 +00:00
function get_item_contact ( $item , $contacts ) {
if ( ! count ( $contacts ) || ( ! is_array ( $item )))
return false ;
foreach ( $contacts as $contact ) {
if ( $contact [ 'id' ] == $item [ 'contact-id' ]) {
return $contact ;
break ; // NOTREACHED
}
}
return false ;
}
2012-02-10 05:18:50 +00:00
function tag_deliver ( $uid , $item_id ) {
2011-11-16 04:30:34 +00:00
2013-06-05 05:52:17 +00:00
// Called when we deliver things that might be tagged in ways that require delivery processing.
// Handles community tagging of posts and also look for mention tags
// and sets up a second delivery chain if appropriate
2011-11-19 06:20:08 +00:00
2011-11-16 04:30:34 +00:00
$a = get_app ();
2012-02-10 05:18:50 +00:00
$mention = false ;
2011-11-16 04:30:34 +00:00
2014-08-20 04:31:33 +00:00
/**
* Fetch stuff we need - a channel and an item
*/
2012-10-08 07:23:43 +00:00
$u = q ( " select * from channel where channel_id = %d limit 1 " ,
2012-02-10 05:18:50 +00:00
intval ( $uid )
2011-11-16 04:30:34 +00:00
);
2013-02-11 08:20:14 +00:00
if ( ! $u )
2011-11-16 04:30:34 +00:00
return ;
2012-10-08 07:23:43 +00:00
2011-11-19 11:13:46 +00:00
$i = q ( " select * from item where id = %d and uid = %d limit 1 " ,
2011-11-16 04:30:34 +00:00
intval ( $item_id ),
intval ( $uid )
);
2013-06-05 05:52:17 +00:00
if ( ! $i )
2011-11-16 04:30:34 +00:00
return ;
2013-01-13 02:06:34 +00:00
$i = fetch_post_tags ( $i );
2011-11-16 04:30:34 +00:00
$item = $i [ 0 ];
2014-08-21 06:01:25 +00:00
if (( $item [ 'source_xchan' ]) && ( $item [ 'item_flags' ] & ITEM_UPLINK )
&& ( $item [ 'item_flags' ] & ITEM_THREAD_TOP ) && ( $item [ 'edited' ] != $item [ 'created' ])) {
// this is an update (edit) to a post which was already processed by us and has a second delivery chain
2013-12-20 04:23:19 +00:00
// Just start the second delivery chain to deliver the updated post
proc_run ( 'php' , 'include/notifier.php' , 'tgroup' , $item [ 'id' ]);
return ;
}
2013-06-05 05:52:17 +00:00
2014-08-20 04:31:33 +00:00
/**
* Seems like a good place to plug in a poke notification .
*/
2014-06-05 05:15:52 +00:00
if ( stristr ( $item [ 'verb' ], ACTIVITY_POKE )) {
$poke_notify = true ;
if (( $item [ 'obj_type' ] == " " ) || ( $item [ 'obj_type' ] !== ACTIVITY_OBJ_PERSON ) || ( ! $item [ 'object' ]))
$poke_notify = false ;
$obj = json_decode_plus ( $item [ 'object' ]);
if ( $obj ) {
if ( $obj [ 'id' ] !== $u [ 0 ][ 'channel_hash' ])
$poke_notify = false ;
}
$verb = urldecode ( substr ( $item [ 'verb' ], strpos ( $item [ 'verb' ], '#' ) + 1 ));
if ( $poke_notify ) {
require_once ( 'include/enotify.php' );
notification ( array (
'to_xchan' => $u [ 0 ][ 'channel_hash' ],
'from_xchan' => $item [ 'author_xchan' ],
'type' => NOTIFY_POKE ,
'item' => $item ,
'link' => $i [ 0 ][ 'llink' ],
'verb' => ACTIVITY_POKE ,
'activity' => $verb ,
'otype' => 'item'
));
}
}
2014-08-20 04:31:33 +00:00
/**
* Do community tagging
*/
2013-06-05 05:52:17 +00:00
if ( $item [ 'obj_type' ] === ACTIVITY_OBJ_TAGTERM ) {
// We received a community tag activity for a post.
// See if we are the owner of the parent item and have given permission to tag our posts.
// If so tag the parent post.
2013-06-21 04:19:22 +00:00
logger ( 'tag_deliver: community tag activity received' );
2013-06-05 05:52:17 +00:00
if (( $item [ 'owner_xchan' ] === $u [ 0 ][ 'channel_hash' ]) && ( ! get_pconfig ( $u [ 0 ][ 'channel_id' ], 'system' , 'blocktags' ))) {
2014-03-31 03:53:59 +00:00
logger ( 'tag_deliver: community tag recipient: ' . $u [ 0 ][ 'channel_name' ]);
2013-08-06 10:54:49 +00:00
$j_tgt = json_decode_plus ( $item [ 'target' ]);
2013-06-21 04:19:22 +00:00
if ( $j_tgt && $j_tgt [ 'id' ]) {
2013-06-05 05:52:17 +00:00
$p = q ( " select * from item where mid = '%s' and uid = %d limit 1 " ,
2013-06-21 04:19:22 +00:00
dbesc ( $j_tgt [ 'id' ]),
2013-06-05 05:52:17 +00:00
intval ( $u [ 0 ][ 'channel_id' ])
);
if ( $p ) {
2013-08-06 10:54:49 +00:00
$j_obj = json_decode_plus ( $item [ 'object' ]);
2013-06-21 04:19:22 +00:00
logger ( 'tag_deliver: tag object: ' . print_r ( $j_obj , true ), LOGGER_DATA );
2013-06-05 05:52:17 +00:00
if ( $j_obj && $j_obj [ 'id' ] && $j_obj [ 'title' ]) {
2013-07-01 06:04:27 +00:00
if ( is_array ( $j_obj [ 'link' ]))
$taglink = get_rel_link ( $j_obj [ 'link' ], 'alternate' );
2014-04-01 00:03:07 +00:00
2013-07-01 06:04:27 +00:00
store_item_tag ( $u [ 0 ][ 'channel_id' ], $p [ 0 ][ 'id' ], TERM_OBJ_POST , TERM_HASHTAG , $j_obj [ 'title' ], $j_obj [ 'id' ]);
2014-02-17 00:04:46 +00:00
$x = q ( " update item set edited = '%s', received = '%s', changed = '%s' where mid = '%s' and uid = %d limit 1 " ,
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
dbesc ( $j_tgt [ 'id' ]),
intval ( $u [ 0 ][ 'channel_id' ])
);
2013-06-05 05:52:17 +00:00
proc_run ( 'php' , 'include/notifier.php' , 'edit_post' , $p [ 0 ][ 'id' ]);
}
}
}
}
2013-06-21 04:19:22 +00:00
else
logger ( 'tag_deliver: tag permission denied for ' . $u [ 0 ][ 'channel_address' ]);
2013-06-05 05:52:17 +00:00
}
2014-08-20 04:31:33 +00:00
/**
* A " union " is a message which our channel has sourced from another channel .
* This sets up a second delivery chain just like forum tags do .
* Find out if this is a source - able post .
*/
2013-09-27 02:34:45 +00:00
$union = check_item_source ( $uid , $item );
if ( $union )
logger ( 'check_item_source returns true' );
2014-02-13 22:20:23 +00:00
// This might be a followup (e.g. comment) by the original post author to a tagged forum
2013-06-29 09:04:44 +00:00
// If so setup a second delivery chain
if ( ! ( $item [ 'item_flags' ] & ITEM_THREAD_TOP )) {
$x = q ( " select * from item where id = parent and parent = %d and uid = %d limit 1 " ,
intval ( $item [ 'parent' ]),
intval ( $uid )
);
2013-09-05 06:15:53 +00:00
if (( $x ) && ( $x [ 0 ][ 'item_flags' ] & ITEM_UPLINK )) {
2014-08-21 06:01:25 +00:00
start_delivery_chain ( $u [ 0 ], $item , $item_id , $x [ 0 ]);
2013-06-29 09:04:44 +00:00
}
}
2014-08-20 04:31:33 +00:00
/**
* Now we 've got those out of the way. Let' s see if this is a post that ' s tagged for re - delivery
*/
2013-01-13 02:06:34 +00:00
$terms = get_terms_oftype ( $item [ 'term' ], TERM_MENTION );
2013-06-29 09:04:44 +00:00
if ( $terms )
logger ( 'tag_deliver: post mentions: ' . print_r ( $terms , true ), LOGGER_DATA );
2013-01-13 02:06:34 +00:00
2013-02-11 07:19:52 +00:00
$link = normalise_link ( $a -> get_baseurl () . '/channel/' . $u [ 0 ][ 'channel_address' ]);
2011-11-16 04:30:34 +00:00
2013-01-13 02:06:34 +00:00
if ( $terms ) {
foreach ( $terms as $term ) {
2014-05-21 20:23:18 +00:00
if ( link_compare ( $term [ 'url' ], $link )) {
2012-02-10 05:18:50 +00:00
$mention = true ;
2013-01-13 02:06:34 +00:00
break ;
2011-11-16 04:30:34 +00:00
}
}
2013-01-13 02:06:34 +00:00
}
2011-11-16 04:30:34 +00:00
2013-01-13 02:06:34 +00:00
if ( $mention ) {
2013-02-11 07:19:52 +00:00
logger ( 'tag_deliver: mention found for ' . $u [ 0 ][ 'channel_name' ]);
2013-01-13 02:06:34 +00:00
$r = q ( " update item set item_flags = ( item_flags | %d ) where id = %d limit 1 " ,
intval ( ITEM_MENTIONSME ),
intval ( $item_id )
);
2011-11-16 04:30:34 +00:00
2013-09-27 02:34:45 +00:00
// At this point we've determined that the person receiving this post was mentioned in it or it is a union.
// Now let's check if this mention was inside a reshare so we don't spam a forum
2013-11-05 00:44:23 +00:00
// If it's private we may have to unobscure it momentarily so that we can parse it.
$body = '' ;
if ( $item [ 'item_flags' ] & ITEM_OBSCURED ) {
$key = get_config ( 'system' , 'prvkey' );
if ( $item [ 'body' ])
2013-11-20 23:20:12 +00:00
$body = crypto_unencapsulate ( json_decode_plus ( $item [ 'body' ]), $key );
2013-11-05 00:44:23 +00:00
}
else
$body = $item [ 'body' ];
2013-01-13 02:35:27 +00:00
2013-11-05 00:44:23 +00:00
$body = preg_replace ( '/\[share(.*?)\[\/share\]/' , '' , $body );
2013-01-13 02:35:27 +00:00
2014-04-20 05:53:42 +00:00
$tagged = false ;
$plustagged = false ;
2014-05-21 20:23:18 +00:00
$pattern = '/@\!?\[zrl\=' . preg_quote ( $term [ 'url' ], '/' ) . '\]' . preg_quote ( $term [ 'term' ], '/' ) . '\[\/zrl\]/' ;
2014-04-20 05:53:42 +00:00
if ( preg_match ( $pattern , $body , $matches ))
$tagged = true ;
2014-05-21 20:23:18 +00:00
$pattern = '/@\!?\[zrl\=' . preg_quote ( $term [ 'url' ], '/' ) . '\]' . preg_quote ( $term [ 'term' ] . '+' , '/' ) . '\[\/zrl\]/' ;
2014-04-20 05:53:42 +00:00
if ( preg_match ( $pattern , $body , $matches ))
$plustagged = true ;
2013-02-11 23:51:43 +00:00
2014-04-20 05:53:42 +00:00
if ( ! ( $tagged || $plustagged )) {
2013-09-27 02:34:45 +00:00
logger ( 'tag_deliver: mention was in a reshare - ignoring' );
return ;
}
2013-01-13 02:35:27 +00:00
2014-04-26 04:12:43 +00:00
$arr = array ( 'channel_id' => $uid , 'item' => $item , 'body' => $body );
call_hooks ( 'tagged' , $arr );
2014-04-20 05:53:42 +00:00
2014-08-20 04:31:33 +00:00
/**
* Kill two birds with one stone . As long as we ' re here , send a mention notification .
*/
2012-05-18 05:44:52 +00:00
2013-09-27 02:34:45 +00:00
require_once ( 'include/enotify.php' );
notification ( array (
'to_xchan' => $u [ 0 ][ 'channel_hash' ],
'from_xchan' => $item [ 'author_xchan' ],
'type' => NOTIFY_TAGSELF ,
'item' => $item ,
'link' => $i [ 0 ][ 'llink' ],
'verb' => ACTIVITY_TAG ,
'otype' => 'item'
));
2012-05-18 02:35:24 +00:00
2014-04-20 05:53:42 +00:00
// Just a normal tag?
if ( ! $plustagged ) {
logger ( 'tag_deliver: not a plus tag' , LOGGER_DEBUG );
return ;
}
// plustagged - keep going, next check permissions
2013-01-13 02:06:34 +00:00
2013-09-27 02:34:45 +00:00
if ( ! perm_is_allowed ( $uid , $item [ 'author_xchan' ], 'tag_deliver' )) {
logger ( 'tag_delivery denied for uid ' . $uid . ' and xchan ' . $item [ 'author_xchan' ]);
return ;
}
2013-08-06 04:42:55 +00:00
}
2012-05-18 02:35:24 +00:00
2014-01-15 11:12:47 +00:00
if (( ! $mention ) && ( ! $union )) {
logger ( 'tag_deliver: no mention and no union.' );
2013-09-27 02:34:45 +00:00
return ;
2014-01-15 11:12:47 +00:00
}
2013-09-27 02:34:45 +00:00
2012-02-10 08:08:23 +00:00
// tgroup delivery - setup a second delivery chain
// prevent delivery looping - only proceed
// if the message originated elsewhere and is a top-level post
2011-11-19 06:20:08 +00:00
2014-08-21 06:01:25 +00:00
if (( $item [ 'item_flags' ] & ITEM_WALL )
|| ( $item [ 'item_flags' ] & ITEM_ORIGIN )
|| ( ! ( $item [ 'item_flags' ] & ITEM_THREAD_TOP ))
|| ( $item [ 'id' ] != $item [ 'parent' ])) {
2013-08-06 04:42:55 +00:00
logger ( 'tag_deliver: item was local or a comment. rejected.' );
2013-01-14 02:35:12 +00:00
return ;
2013-08-06 04:42:55 +00:00
}
2011-11-16 04:30:34 +00:00
2013-02-12 00:59:48 +00:00
logger ( 'tag_deliver: creating second delivery chain.' );
2014-08-21 06:01:25 +00:00
start_delivery_chain ( $u [ 0 ], $item , $item_id , null );
2012-02-10 08:08:23 +00:00
2011-11-16 04:30:34 +00:00
}
2014-08-20 04:31:33 +00:00
/**
* @ function tgroup_check ( $uid , $item )
*
* This function is called pre - deliver to see if a post matches the criteria to be tag delivered .
* We don ' t actually do anything except check that it matches the criteria .
* This is so that the channel with tag_delivery enabled can receive the post even if they turn off
* permissions for the sender to send their stream . tag_deliver () can ' t be called until the post is actually stored .
* By then it would be too late to reject it .
*/
2011-11-16 04:30:34 +00:00
2012-09-21 00:04:22 +00:00
function tgroup_check ( $uid , $item ) {
$a = get_app ();
$mention = false ;
// check that the message originated elsewhere and is a top-level post
2013-12-17 02:07:41 +00:00
// or is a followup and we have already accepted the top level post as an uplink
2012-09-21 00:04:22 +00:00
2013-08-02 04:24:55 +00:00
if ( $item [ 'mid' ] != $item [ 'parent_mid' ]) {
2013-12-17 02:07:41 +00:00
$r = q ( " select id from item where mid = '%s' and uid = %d and ( item_flags & %d ) limit 1 " ,
2013-08-02 04:24:55 +00:00
dbesc ( $item [ 'parent_mid' ]),
2013-12-17 02:07:41 +00:00
intval ( $uid ),
intval ( ITEM_UPLINK )
2013-07-29 23:51:44 +00:00
);
if ( $r )
return true ;
2012-09-21 00:04:22 +00:00
return false ;
2013-07-29 23:51:44 +00:00
}
2013-06-16 07:57:39 +00:00
if ( ! perm_is_allowed ( $uid , $item [ 'author_xchan' ], 'tag_deliver' ))
return false ;
2012-09-21 00:04:22 +00:00
2013-06-16 07:57:39 +00:00
$u = q ( " select * from channel where channel_id = %d limit 1 " ,
2012-09-21 00:04:22 +00:00
intval ( $uid )
);
2013-06-16 07:57:39 +00:00
if ( ! $u )
return false ;
2012-09-21 00:04:22 +00:00
2013-06-16 07:57:39 +00:00
$terms = get_terms_oftype ( $item [ 'term' ], TERM_MENTION );
2012-09-21 00:04:22 +00:00
2013-07-16 02:04:23 +00:00
if ( $terms )
logger ( 'tgroup_check: post mentions: ' . print_r ( $terms , true ), LOGGER_DATA );
2012-09-21 00:04:22 +00:00
2013-06-16 07:57:39 +00:00
$link = normalise_link ( $a -> get_baseurl () . '/channel/' . $u [ 0 ][ 'channel_address' ]);
2012-09-21 00:04:22 +00:00
2013-06-16 07:57:39 +00:00
if ( $terms ) {
foreach ( $terms as $term ) {
2014-05-21 20:23:18 +00:00
if ( link_compare ( $term [ 'url' ], $link )) {
2012-09-21 00:04:22 +00:00
$mention = true ;
2013-06-16 07:57:39 +00:00
break ;
2012-09-21 00:04:22 +00:00
}
}
2013-06-16 07:57:39 +00:00
}
2012-09-21 00:04:22 +00:00
2013-06-16 07:57:39 +00:00
if ( $mention ) {
logger ( 'tgroup_check: mention found for ' . $u [ 0 ][ 'channel_name' ]);
}
else
2012-09-21 00:04:22 +00:00
return false ;
2013-06-16 07:57:39 +00:00
// At this point we've determined that the person receiving this post was mentioned in it.
// Now let's check if this mention was inside a reshare so we don't spam a forum
2012-09-21 00:04:22 +00:00
2013-06-16 07:57:39 +00:00
$body = preg_replace ( '/\[share(.*?)\[\/share\]/' , '' , $item [ 'body' ]);
2014-05-21 20:23:18 +00:00
$pattern = '/@\!?\[zrl\=' . preg_quote ( $term [ 'url' ], '/' ) . '\]' . preg_quote ( $term [ 'term' ] . '+' , '/' ) . '\[\/zrl\]/' ;
2013-06-16 07:57:39 +00:00
if ( ! preg_match ( $pattern , $body , $matches )) {
logger ( 'tgroup_check: mention was in a reshare - ignoring' );
return false ;
}
2012-09-21 00:04:22 +00:00
return true ;
}
2014-08-21 06:01:25 +00:00
/**
* Sourced and tag - delivered posts are re - targetted for delivery to the connections of the channel
* receiving the post . This starts the second delivery chain , by resetting permissions and ensuring
* that ITEM_UPLINK is set on the parent post , and storing the current owner_xchan as the source_xchan .
* We ' ll become the new owner . If called without $parent , this * is * the parent post .
*/
function start_delivery_chain ( $channel , $item , $item_id , $parent ) {
// Change this copy of the post to a forum head message and deliver to all the tgroup members
// also reset all the privacy bits to the forum default permissions
$private = (( $channel [ 'channel_allow_cid' ] || $channel [ 'channel_allow_gid' ]
|| $channel [ 'channel_deny_cid' ] || $channel [ 'channel_deny_gid' ]) ? 1 : 0 );
$new_public_policy = map_scope ( $channel [ 'channel_r_stream' ], true );
if (( ! $private ) && $new_public_policy )
$private = 1 ;
$flag_bits = $item [ 'item_flags' ] | ITEM_WALL | ITEM_ORIGIN ;
2014-09-05 01:52:37 +00:00
// unset the nocomment bit if it's there.
if ( $flag_bits & ITEM_NOCOMMENT )
$flag_bits = $flag_bits ^ ITEM_NOCOMMENT ;
2014-08-21 06:01:25 +00:00
// maintain the original source, which will be the original item owner and was stored in source_xchan
// when we created the delivery fork
if ( $parent ) {
$r = q ( " update item set source_xchan = '%s' where id = %d limit 1 " ,
dbesc ( $parent [ 'source_xchan' ]),
intval ( $item_id )
);
}
else {
$flag_bits = $flag_bits | ITEM_UPLINK ;
$r = q ( " update item set source_xchan = owner_xchan where id = %d limit 1 " ,
intval ( $item_id )
);
}
$title = $item [ 'title' ];
$body = $item [ 'body' ];
if ( $private ) {
if ( ! ( $flag_bits & ITEM_OBSCURED )) {
$key = get_config ( 'system' , 'pubkey' );
$flag_bits = $flag_bits | ITEM_OBSCURED ;
2014-08-23 00:34:18 +00:00
if ( $title )
2014-08-23 09:45:21 +00:00
$title = json_encode ( crypto_encapsulate ( $title , $key ));
2014-08-23 00:34:18 +00:00
if ( $body )
2014-08-23 09:45:21 +00:00
$body = json_encode ( crypto_encapsulate ( $body , $key ));
2014-08-21 06:01:25 +00:00
}
}
else {
if ( $flag_bits & ITEM_OBSCURED ) {
$key = get_config ( 'system' , 'prvkey' );
$flag_bits = $flag_bits ^ ITEM_OBSCURED ;
2014-08-23 00:34:18 +00:00
if ( $title )
$title = crypto_unencapsulate ( json_decode ( $title , true ), $key );
if ( $body )
$body = crypto_unencapsulate ( json_decode ( $body , true ), $key );
2014-08-21 06:01:25 +00:00
}
}
$r = q ( " update item set item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s',
deny_cid = '%s' , deny_gid = '%s' , item_private = % d , public_policy = '%s' , comment_policy = '%s' , title = '%s' , body = '%s' where id = % d limit 1 " ,
intval ( $flag_bits ),
dbesc ( $channel [ 'channel_hash' ]),
dbesc ( $channel [ 'channel_allow_cid' ]),
dbesc ( $channel [ 'channel_allow_gid' ]),
dbesc ( $channel [ 'channel_deny_cid' ]),
dbesc ( $channel [ 'channel_deny_gid' ]),
intval ( $private ),
dbesc ( $new_public_policy ),
dbesc ( map_scope ( $channel [ 'channel_w_comment' ])),
dbesc ( $title ),
dbesc ( $body ),
intval ( $item_id )
);
if ( $r )
proc_run ( 'php' , 'include/notifier.php' , 'tgroup' , $item_id );
else
logger ( 'start_delivery_chain: failed to update item' );
return ;
}
2012-09-21 00:04:22 +00:00
2013-09-27 02:34:45 +00:00
/**
* @ function check_item_source ( $uid , $item )
* @ param $uid
* @ param $item
*
* @ description
* Checks to see if this item owner is referenced as a source for this channel and if the post
* matches the rules for inclusion in this channel . Returns true if we should create a second delivery
* chain and false if none of the rules apply , or if the item is private .
*/
function check_item_source ( $uid , $item ) {
2014-02-01 04:02:59 +00:00
$r = q ( " select * from source where src_channel_id = %d and ( src_xchan = '%s' || src_xchan = '*' ) limit 1 " ,
2013-09-27 02:34:45 +00:00
intval ( $uid ),
2013-12-20 04:23:19 +00:00
dbesc (( $item [ 'source_xchan' ]) ? $item [ 'source_xchan' ] : $item [ 'owner_xchan' ])
2013-09-27 02:34:45 +00:00
);
2014-09-05 01:52:37 +00:00
2013-09-27 02:34:45 +00:00
if ( ! $r )
return false ;
2014-09-05 01:06:59 +00:00
$x = q ( " select abook_their_perms, abook_flags from abook where abook_channel = %d and abook_xchan = '%s' limit 1 " ,
2013-10-01 04:49:26 +00:00
intval ( $uid ),
dbesc ( $item [ 'owner_xchan' ])
);
2014-09-05 01:52:37 +00:00
2013-10-01 04:49:26 +00:00
if ( ! $x )
return false ;
2014-09-05 01:52:37 +00:00
2013-10-01 04:49:26 +00:00
if ( ! ( $x [ 0 ][ 'abook_their_perms' ] & PERMS_A_REPUBLISH ))
return false ;
2014-09-05 01:06:59 +00:00
if ( $item [ 'item_private' ] && ( ! ( $x [ 0 ][ 'abook_flags' ] & ABOOK_FLAG_FEED )))
return false ;
2013-09-27 02:34:45 +00:00
if ( $r [ 0 ][ 'src_channel_xchan' ] === $item [ 'owner_xchan' ])
return false ;
if ( ! $r [ 0 ][ 'src_patt' ])
return true ;
2013-09-27 02:58:24 +00:00
require_once ( 'include/html2plain.php' );
$text = prepare_text ( $item [ 'body' ], $item [ 'mimetype' ]);
$text = html2plain ( $text );
2013-09-27 02:34:45 +00:00
$tags = (( count ( $items [ 'term' ])) ? $items [ 'term' ] : false );
$words = explode ( " \n " , $r [ 0 ][ 'src_patt' ]);
if ( $words ) {
foreach ( $words as $word ) {
if ( substr ( $word , 0 , 1 ) === '#' && $tags ) {
foreach ( $tags as $t )
2014-02-01 04:02:59 +00:00
if (( $t [ 'type' ] == TERM_HASHTAG ) && (( substr ( $t , 1 ) === substr ( $word , 1 )) || ( substr ( $word , 1 ) === '*' )))
2013-09-27 02:34:45 +00:00
return true ;
}
2013-09-27 02:58:24 +00:00
if ( stristr ( $text , $word ) !== false )
2013-09-27 02:34:45 +00:00
return true ;
}
}
return false ;
}
2012-12-06 00:44:07 +00:00
function mail_store ( $arr ) {
if ( ! $arr [ 'channel_id' ]) {
logger ( 'mail_store: no uid' );
return 0 ;
}
if (( strpos ( $arr [ 'body' ], '<' ) !== false ) || ( strpos ( $arr [ 'body' ], '>' ) !== false ))
$arr [ 'body' ] = escape_tags ( $arr [ 'body' ]);
2013-08-20 04:19:39 +00:00
if ( array_key_exists ( 'attach' , $arr ) && is_array ( $arr [ 'attach' ]))
$arr [ 'attach' ] = json_encode ( $arr [ 'attach' ]);
2012-12-06 00:44:07 +00:00
$arr [ 'account_id' ] = (( x ( $arr , 'account_id' )) ? intval ( $arr [ 'account_id' ]) : 0 );
2013-03-22 01:25:41 +00:00
$arr [ 'mid' ] = (( x ( $arr , 'mid' )) ? notags ( trim ( $arr [ 'mid' ])) : random_string ());
2012-12-06 00:44:07 +00:00
$arr [ 'from_xchan' ] = (( x ( $arr , 'from_xchan' )) ? notags ( trim ( $arr [ 'from_xchan' ])) : '' );
$arr [ 'to_xchan' ] = (( x ( $arr , 'to_xchan' )) ? notags ( trim ( $arr [ 'to_xchan' ])) : '' );
$arr [ 'created' ] = (( x ( $arr , 'created' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'created' ]) : datetime_convert ());
2014-09-09 03:35:15 +00:00
$arr [ 'expires' ] = (( x ( $arr , 'expires' ) !== false ) ? datetime_convert ( 'UTC' , 'UTC' , $arr [ 'expires' ]) : NULL_DATE );
2012-12-06 00:44:07 +00:00
$arr [ 'title' ] = (( x ( $arr , 'title' )) ? notags ( trim ( $arr [ 'title' ])) : '' );
2013-03-22 01:25:41 +00:00
$arr [ 'parent_mid' ] = (( x ( $arr , 'parent_mid' )) ? notags ( trim ( $arr [ 'parent_mid' ])) : '' );
2012-12-06 00:44:07 +00:00
$arr [ 'body' ] = (( x ( $arr , 'body' )) ? trim ( $arr [ 'body' ]) : '' );
2013-08-20 04:19:39 +00:00
2012-12-06 00:44:07 +00:00
$arr [ 'mail_flags' ] = (( x ( $arr , 'mail_flags' )) ? intval ( $arr [ 'mail_flags' ]) : 0 );
2012-12-06 01:11:38 +00:00
2013-03-22 01:25:41 +00:00
if ( ! $arr [ 'parent_mid' ]) {
2012-12-06 01:11:38 +00:00
logger ( 'mail_store: missing parent' );
2013-03-22 01:25:41 +00:00
$arr [ 'parent_mid' ] = $arr [ 'mid' ];
2012-12-06 01:11:38 +00:00
}
2013-03-22 01:25:41 +00:00
$r = q ( " SELECT `id` FROM mail WHERE `mid` = '%s' AND channel_id = %d LIMIT 1 " ,
dbesc ( $arr [ 'mid' ]),
2012-12-06 00:44:07 +00:00
intval ( $arr [ 'channel_id' ])
);
if ( $r ) {
logger ( 'mail_store: duplicate item ignored. ' . print_r ( $arr , true ));
return 0 ;
}
call_hooks ( 'post_mail' , $arr );
if ( x ( $arr , 'cancel' )) {
logger ( 'mail_store: post cancelled by plugin.' );
return 0 ;
}
dbesc_array ( $arr );
logger ( 'mail_store: ' . print_r ( $arr , true ), LOGGER_DATA );
$r = dbq ( " INSERT INTO mail (` "
. implode ( " `, ` " , array_keys ( $arr ))
. " `) VALUES (' "
. implode ( " ', ' " , array_values ( $arr ))
. " ') " );
// find the item we just created
2013-03-22 01:25:41 +00:00
$r = q ( " SELECT `id` FROM mail WHERE `mid` = '%s' AND `channel_id` = %d ORDER BY `id` ASC " ,
$arr [ 'mid' ], // already dbesc'd
2012-12-06 00:44:07 +00:00
intval ( $arr [ 'channel_id' ])
);
if ( $r ) {
$current_post = $r [ 0 ][ 'id' ];
logger ( 'mail_store: created item ' . $current_post , LOGGER_DEBUG );
2013-01-06 02:08:06 +00:00
$arr [ 'id' ] = $current_post ; // for notification
2012-12-06 00:44:07 +00:00
}
else {
logger ( 'mail_store: could not locate created item' );
return 0 ;
}
if ( count ( $r ) > 1 ) {
logger ( 'mail_store: duplicated post occurred. Removing duplicates.' );
2013-03-22 01:25:41 +00:00
q ( " DELETE FROM mail WHERE `mid` = '%s' AND `channel_id` = %d AND `id` != %d " ,
$arr [ 'mid' ],
2012-12-06 00:44:07 +00:00
intval ( $arr [ 'channel_id' ]),
intval ( $current_post )
);
}
2013-01-06 02:08:06 +00:00
else {
require_once ( 'include/enotify.php' );
$notif_params = array (
'from_xchan' => $arr [ 'from_xchan' ],
'to_xchan' => $arr [ 'to_xchan' ],
'type' => NOTIFY_MAIL ,
'item' => $arr ,
'verb' => ACTIVITY_POST ,
'otype' => 'mail'
);
notification ( $notif_params );
}
2012-12-06 00:44:07 +00:00
call_hooks ( 'post_mail_end' , $arr );
return $current_post ;
}
2011-02-08 05:16:39 +00:00
/**
2010-10-22 04:48:22 +00:00
*
* consume_feed - process atom feed and update anything / everything we might need to update
*
2011-02-08 05:16:39 +00:00
* $xml = the ( atom ) feed to consume - RSS isn ' t as fully supported but may work for simple feeds .
*
2010-10-22 04:48:22 +00:00
* $importer = the contact_record ( joined to user_record ) of the local user who owns this relationship .
* It is this person ' s stuff that is going to be updated .
* $contact = the person who is sending us stuff . If not set , we MAY be processing a " follow " activity
* from an external network and MAY create an appropriate contact record . Otherwise , we MUST
* have a contact record .
2010-12-01 21:39:00 +00:00
* $hub = should we find a hub declation in the feed , pass it back to our calling process , who might ( or
2010-10-22 04:48:22 +00:00
* might not ) try and subscribe to it .
2011-10-04 11:38:58 +00:00
* $datedir sorts in reverse order
* $pass - by default ( $pass = 0 ) we cannot guarantee that a parent item has been
* imported prior to its children being seen in the stream unless we are certain
* of how the feed is arranged / ordered .
* With $pass = 1 , we only pull parent items out of the stream .
* With $pass = 2 , we only pull children ( comments / likes ) .
2010-10-22 04:48:22 +00:00
*
2011-10-04 11:38:58 +00:00
* So running this twice , first with pass 1 and then with pass 2 will do the right
* thing regardless of feed ordering . This won ' t be adequate in a fully - threaded
* model where comments can have sub - threads . That would require some massive sorting
* to get all the feed items into a mostly linear ordering , and might still require
* recursion .
2010-10-22 04:48:22 +00:00
*/
2014-08-20 05:47:11 +00:00
function consume_feed ( $xml , $importer , & $contact , $pass = 0 ) {
2010-10-01 02:41:22 +00:00
2011-06-29 04:11:52 +00:00
require_once ( 'library/simplepie/simplepie.inc' );
2010-10-01 02:41:22 +00:00
2011-08-04 04:05:39 +00:00
if ( ! strlen ( $xml )) {
logger ( 'consume_feed: empty input' );
return ;
}
2013-09-30 03:34:05 +00:00
2010-10-01 02:41:22 +00:00
$feed = new SimplePie ();
$feed -> set_raw_data ( $xml );
$feed -> init ();
2011-01-31 03:38:03 +00:00
if ( $feed -> error ())
logger ( 'consume_feed: Error parsing XML: ' . $feed -> error ());
2011-04-05 02:36:18 +00:00
$permalink = $feed -> get_permalink ();
2011-01-31 03:38:03 +00:00
2010-10-01 02:41:22 +00:00
// Check at the feed level for updated contact name and/or photo
2011-02-08 12:25:27 +00:00
// process any deleted entries
2010-10-01 02:41:22 +00:00
2011-02-08 12:25:27 +00:00
$del_entries = $feed -> get_feed_tags ( NAMESPACE_TOMB , 'deleted-entry' );
2011-10-04 10:06:34 +00:00
if ( is_array ( $del_entries ) && count ( $del_entries ) && $pass != 2 ) {
2011-02-08 12:25:27 +00:00
foreach ( $del_entries as $dentry ) {
2010-10-01 02:41:22 +00:00
$deleted = false ;
2011-02-08 12:25:27 +00:00
if ( isset ( $dentry [ 'attribs' ][ '' ][ 'ref' ])) {
2013-03-22 01:25:41 +00:00
$mid = $dentry [ 'attribs' ][ '' ][ 'ref' ];
2010-10-01 02:41:22 +00:00
$deleted = true ;
2011-02-08 12:25:27 +00:00
if ( isset ( $dentry [ 'attribs' ][ '' ][ 'when' ])) {
$when = $dentry [ 'attribs' ][ '' ][ 'when' ];
2010-10-01 02:41:22 +00:00
$when = datetime_convert ( 'UTC' , 'UTC' , $when , 'Y-m-d H:i:s' );
}
else
$when = datetime_convert ( 'UTC' , 'UTC' , 'now' , 'Y-m-d H:i:s' );
}
2014-08-20 04:31:33 +00:00
2010-10-22 04:48:22 +00:00
if ( $deleted && is_array ( $contact )) {
2014-08-20 11:38:17 +00:00
$r = q ( " SELECT * from item where mid = '%s' and author_xchan = '%s' and uid = %d limit 1 " ,
2014-09-09 23:28:33 +00:00
dbesc ( base64url_encode ( $mid )),
2014-08-20 11:38:17 +00:00
dbesc ( $contact [ 'xchan_hash' ]),
intval ( $importer [ 'channel_id' ])
2010-10-01 02:41:22 +00:00
);
2014-08-20 11:38:17 +00:00
if ( $r ) {
2010-10-01 02:41:22 +00:00
$item = $r [ 0 ];
2011-02-08 12:25:27 +00:00
2014-08-20 11:38:17 +00:00
if ( ! ( $item [ 'item_restrict' ] & ITEM_DELETED )) {
2014-09-09 23:28:33 +00:00
logger ( 'consume_feed: deleting item ' . $item [ 'id' ] . ' mid=' . base64url_decode ( $item [ 'mid' ]), LOGGER_DEBUG );
2014-08-20 11:38:17 +00:00
drop_item ( $item [ 'id' ], false );
2010-10-01 02:41:22 +00:00
}
}
}
2011-02-08 12:25:27 +00:00
}
}
// Now process the feed
2012-07-19 00:08:03 +00:00
if ( $feed -> get_item_quantity ()) {
2011-02-08 12:25:27 +00:00
2014-08-20 11:38:17 +00:00
logger ( 'consume_feed: feed item count = ' . $feed -> get_item_quantity (), LOGGER_DEBUG );
2010-10-01 02:41:22 +00:00
2014-08-20 11:38:17 +00:00
$items = $feed -> get_items ();
2010-10-01 02:41:22 +00:00
2011-02-08 12:25:27 +00:00
foreach ( $items as $item ) {
2012-07-19 00:08:03 +00:00
$is_reply = false ;
2014-09-09 23:28:33 +00:00
$item_id = base64url_encode ( $item -> get_id ());
2013-09-30 03:34:05 +00:00
2014-08-20 11:38:17 +00:00
logger ( 'consume_feed: processing ' . $item_id , LOGGER_DEBUG );
2013-09-30 03:34:05 +00:00
2010-10-01 02:41:22 +00:00
$rawthread = $item -> get_item_tags ( NAMESPACE_THREAD , 'in-reply-to' );
if ( isset ( $rawthread [ 0 ][ 'attribs' ][ '' ][ 'ref' ])) {
$is_reply = true ;
2014-09-09 23:28:33 +00:00
$parent_mid = base64url_encode ( $rawthread [ 0 ][ 'attribs' ][ '' ][ 'ref' ]);
2010-10-01 02:41:22 +00:00
}
2013-08-07 10:54:47 +00:00
if ( $is_reply ) {
2011-10-20 04:54:33 +00:00
if ( $pass == 1 )
continue ;
2011-02-09 02:44:30 +00:00
2012-09-21 00:04:22 +00:00
2010-10-01 02:41:22 +00:00
// Have we seen it? If not, import it.
2012-07-19 00:08:03 +00:00
2014-09-09 23:28:33 +00:00
$item_id = base64url_encode ( $item -> get_id ());
2014-08-21 01:35:36 +00:00
$author = array ();
$datarray = get_atom_elements ( $feed , $item , $author );
2011-02-09 02:44:30 +00:00
2014-09-24 21:27:18 +00:00
if (( ! x ( $author , 'author_name' )) || ( $author [ 'author_is_feed' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_name' ] = $contact [ 'xchan_name' ];
2014-09-24 21:27:18 +00:00
if (( ! x ( $author , 'author_link' )) || ( $author [ 'author_is_feed' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_link' ] = $contact [ 'xchan_url' ];
2014-09-24 21:27:18 +00:00
if (( ! x ( $author , 'author_photo' )) || ( $author [ 'author_is_feed' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_photo' ] = $contact [ 'xchan_photo_m' ];
2011-07-06 02:55:09 +00:00
2014-09-12 00:27:49 +00:00
$datarray [ 'author_xchan' ] = '' ;
if ( $author [ 'author_link' ] != $contact [ 'xchan_url' ]) {
2014-09-25 18:47:06 +00:00
$x = import_author_unknown ( array ( 'name' => $author [ 'author_name' ], 'url' => $author [ 'author_link' ], 'photo' => array ( 'src' => $author [ 'author_photo' ])));
2014-09-12 00:27:49 +00:00
if ( $x )
$datarray [ 'author_xchan' ] = $x ;
}
if ( ! $datarray [ 'author_xchan' ])
$datarray [ 'author_xchan' ] = $contact [ 'xchan_hash' ];
$datarray [ 'owner_xchan' ] = $contact [ 'xchan_hash' ];
2014-08-20 11:38:17 +00:00
$r = q ( " SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1 " ,
2010-10-01 02:41:22 +00:00
dbesc ( $item_id ),
2013-09-30 03:34:05 +00:00
intval ( $importer [ 'channel_id' ])
2010-10-01 02:41:22 +00:00
);
2011-02-09 02:44:30 +00:00
2011-03-01 02:24:32 +00:00
// Update content if 'updated' changes
2013-09-30 03:34:05 +00:00
if ( $r ) {
2014-08-20 11:38:17 +00:00
if (( x ( $datarray , 'edited' ) !== false )
&& ( datetime_convert ( 'UTC' , 'UTC' , $datarray [ 'edited' ]) !== $r [ 0 ][ 'edited' ])) {
2012-06-12 01:14:49 +00:00
// do not accept (ignore) an earlier edit than one we currently have.
2012-06-12 09:47:05 +00:00
if ( datetime_convert ( 'UTC' , 'UTC' , $datarray [ 'edited' ]) < $r [ 0 ][ 'edited' ])
2012-06-12 01:14:49 +00:00
continue ;
2014-08-20 11:38:17 +00:00
update_feed_item ( $importer [ 'channel_id' ], $datarray );
2011-03-01 02:24:32 +00:00
}
2010-10-01 02:41:22 +00:00
continue ;
}
2011-02-09 02:44:30 +00:00
2013-03-22 01:25:41 +00:00
$datarray [ 'parent_mid' ] = $parent_mid ;
2013-09-30 03:34:05 +00:00
$datarray [ 'uid' ] = $importer [ 'channel_id' ];
2014-08-21 01:35:36 +00:00
2011-10-24 11:17:46 +00:00
2014-08-20 11:38:17 +00:00
logger ( 'consume_feed: ' . print_r ( $datarray , true ), LOGGER_DATA );
2013-09-30 03:34:05 +00:00
2014-09-01 03:51:05 +00:00
$xx = item_store ( $datarray );
2013-09-11 02:06:06 +00:00
$r = $xx [ 'item_id' ];
2010-10-01 02:41:22 +00:00
continue ;
}
else {
2011-03-01 02:24:32 +00:00
2010-10-01 02:41:22 +00:00
// Head post of a conversation. Have we seen it? If not, import it.
2014-09-09 23:28:33 +00:00
$item_id = base64url_encode ( $item -> get_id ());
2014-08-21 01:35:36 +00:00
$author = array ();
$datarray = get_atom_elements ( $feed , $item , $author );
2011-03-01 02:24:32 +00:00
2011-05-06 13:30:33 +00:00
if ( is_array ( $contact )) {
2014-09-24 21:27:18 +00:00
if (( ! x ( $author , 'author_name' )) || ( $author [ 'author_is_feed' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_name' ] = $contact [ 'xchan_name' ];
2014-09-24 21:27:18 +00:00
if (( ! x ( $author , 'author_link' )) || ( $author [ 'author_is_feed' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_link' ] = $contact [ 'xchan_url' ];
2014-09-24 21:27:18 +00:00
if (( ! x ( $author , 'author_photo' )) || ( $author [ 'author_is_feed' ]))
2014-08-21 01:35:36 +00:00
$author [ 'author_photo' ] = $contact [ 'xchan_photo_m' ];
2011-05-06 13:30:33 +00:00
}
2014-08-21 01:35:36 +00:00
if (( ! x ( $author , 'author_name' )) || ( ! x ( $author , 'author_link' ))) {
logger ( 'consume_feed: no author information! ' . print_r ( $author , true ));
2012-02-25 04:03:13 +00:00
continue ;
}
2014-09-12 00:27:49 +00:00
$datarray [ 'author_xchan' ] = '' ;
if ( $author [ 'author_link' ] != $contact [ 'xchan_url' ]) {
2014-09-12 07:59:23 +00:00
$x = import_author_unknown ( array ( 'name' => $author [ 'author_name' ], 'url' => $author [ 'author_link' ], 'photo' => array ( 'src' => $author [ 'author_photo' ])));
2014-09-12 00:27:49 +00:00
if ( $x )
$datarray [ 'author_xchan' ] = $x ;
}
if ( ! $datarray [ 'author_xchan' ])
$datarray [ 'author_xchan' ] = $contact [ 'xchan_hash' ];
$datarray [ 'owner_xchan' ] = $contact [ 'xchan_hash' ];
2011-06-14 02:06:49 +00:00
2014-08-20 11:38:17 +00:00
$r = q ( " SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1 " ,
2010-10-01 02:41:22 +00:00
dbesc ( $item_id ),
2013-09-30 03:34:05 +00:00
intval ( $importer [ 'channel_id' ])
2010-10-01 02:41:22 +00:00
);
2011-03-01 02:24:32 +00:00
// Update content if 'updated' changes
2013-09-30 03:34:05 +00:00
if ( $r ) {
2014-08-20 11:38:17 +00:00
if (( x ( $datarray , 'edited' ) !== false )
&& ( datetime_convert ( 'UTC' , 'UTC' , $datarray [ 'edited' ]) !== $r [ 0 ][ 'edited' ])) {
2012-06-12 01:14:49 +00:00
// do not accept (ignore) an earlier edit than one we currently have.
2012-06-12 09:47:05 +00:00
if ( datetime_convert ( 'UTC' , 'UTC' , $datarray [ 'edited' ]) < $r [ 0 ][ 'edited' ])
2012-06-12 01:14:49 +00:00
continue ;
2014-08-20 11:38:17 +00:00
update_feed_item ( $importer [ 'channel_id' ], $datarray );
2011-03-01 02:24:32 +00:00
}
2010-10-01 02:41:22 +00:00
continue ;
}
2010-10-25 03:39:24 +00:00
2011-07-06 02:55:09 +00:00
2013-03-22 01:25:41 +00:00
$datarray [ 'parent_mid' ] = $item_id ;
2013-09-30 03:34:05 +00:00
$datarray [ 'uid' ] = $importer [ 'channel_id' ];
2014-09-12 00:27:49 +00:00
2014-08-21 01:35:36 +00:00
if ( ! link_compare ( $author [ 'owner_link' ], $contact [ 'xchan_url' ])) {
logger ( 'consume_feed: Correcting item owner.' , LOGGER_DEBUG );
2014-09-01 03:51:05 +00:00
$author [ 'owner_name' ] = $contact [ 'name' ];
$author [ 'owner_link' ] = $contact [ 'url' ];
$author [ 'owner_avatar' ] = $contact [ 'thumb' ];
2014-08-21 01:35:36 +00:00
}
2012-09-21 00:04:22 +00:00
2014-09-12 00:27:49 +00:00
logger ( 'consume_feed: author ' . print_r ( $author , true ), LOGGER_DEBUG );
2014-09-01 03:51:05 +00:00
2014-08-20 11:38:17 +00:00
logger ( 'consume_feed: ' . print_r ( $datarray , true ), LOGGER_DATA );
2012-09-21 00:04:22 +00:00
2014-09-01 03:51:05 +00:00
$xx = item_store ( $datarray );
2013-09-11 02:06:06 +00:00
$r = $xx [ 'item_id' ];
2010-10-01 02:41:22 +00:00
continue ;
}
}
}
2013-09-30 03:34:05 +00:00
2014-08-20 11:38:17 +00:00
}
function update_feed_item ( $uid , $datarray ) {
2014-09-09 23:28:33 +00:00
logger ( 'update_feed_item: not implemented! ' . $uid . ' ' . print_r ( $datarray , true ), LOGGER_DATA );
2014-08-20 11:38:17 +00:00
2010-10-01 04:38:45 +00:00
}
2011-10-02 23:18:01 +00:00
2014-08-20 05:47:11 +00:00
function handle_feed ( $uid , $abook_id , $url ) {
require_once ( 'include/Contact.php' );
$channel = channelx_by_n ( $uid );
if ( ! $channel )
return ;
$x = q ( " select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d limit 1 " ,
dbesc ( $abook_id ),
intval ( $uid )
);
$recurse = 0 ;
$z = z_fetch_url ( $url , false , $recurse , array ( 'novalidate' => true ));
2014-09-01 03:51:05 +00:00
//logger('handle_feed:' . print_r($z,true));
2014-08-20 05:47:11 +00:00
if ( $z [ 'success' ]) {
consume_feed ( $z [ 'body' ], $channel , $x [ 0 ], 0 );
consume_feed ( $z [ 'body' ], $channel , $x [ 0 ], 1 );
}
}
2010-10-01 04:38:45 +00:00
2013-06-13 04:12:27 +00:00
function atom_author ( $tag , $name , $uri , $h , $w , $type , $photo ) {
2010-11-02 00:56:36 +00:00
$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 .= " <name> $name </name> \r \n " ;
$o .= " <uri> $uri </uri> \r \n " ;
2013-06-13 04:12:27 +00:00
$o .= '<link rel="photo" type="' . $type . '" media:width="' . $w . '" media:height="' . $h . '" href="' . $photo . '" />' . " \r \n " ;
$o .= '<link rel="avatar" type="' . $type . '" media:width="' . $w . '" media:height="' . $h . '" href="' . $photo . '" />' . " \r \n " ;
2010-12-25 02:32:23 +00:00
call_hooks ( 'atom_author' , $o );
2010-11-02 00:56:36 +00:00
$o .= " </ $tag > \r \n " ;
return $o ;
}
2012-05-28 04:01:58 +00:00
function atom_entry ( $item , $type , $author , $owner , $comment = false , $cid = 0 ) {
2010-11-02 00:56:36 +00:00
2011-05-01 00:24:37 +00:00
$a = get_app ();
2011-10-15 10:26:37 +00:00
if ( ! $item [ 'parent' ])
return ;
2010-11-02 00:56:36 +00:00
if ( $item [ 'deleted' ])
2013-03-22 01:25:41 +00:00
return '<at:deleted-entry ref="' . xmlify ( $item [ 'mid' ]) . '" when="' . xmlify ( datetime_convert ( 'UTC' , 'UTC' , $item [ 'edited' ] . '+00:00' , ATOM_TIME )) . '" />' . " \r \n " ;
2010-11-02 00:56:36 +00:00
2011-05-01 00:24:37 +00:00
if ( $item [ 'allow_cid' ] || $item [ 'allow_gid' ] || $item [ 'deny_cid' ] || $item [ 'deny_gid' ])
2012-05-28 04:01:58 +00:00
$body = fix_private_photos ( $item [ 'body' ], $owner [ 'uid' ], $item , $cid );
2011-05-01 00:24:37 +00:00
else
$body = $item [ 'body' ];
2010-11-02 00:56:36 +00:00
2010-11-02 06:42:26 +00:00
$o = " \r \n \r \n <entry> \r \n " ;
2010-11-02 00:56:36 +00:00
if ( is_array ( $author ))
2013-06-13 04:12:27 +00:00
$o .= atom_author ( 'author' , $author [ 'xchan_name' ], $author [ 'xchan_url' ], 80 , 80 , $author [ 'xchan_photo_mimetype' ], $author [ 'xchan_photo_m' ]);
2010-11-02 00:56:36 +00:00
else
2013-06-13 04:12:27 +00:00
$o .= atom_author ( 'author' , $item [ 'author' ][ 'xchan_name' ], $item [ 'author' ][ 'xchan_url' ], 80 , 80 , $item [ 'author' ][ 'xchan_photo_mimetype' ], $item [ 'author' ][ 'xchan_photo_m' ]);
$o .= atom_author ( 'zot:owner' , $item [ 'owner' ][ 'xchan_name' ], $item [ 'owner' ][ 'xchan_url' ], 80 , 80 , $item [ 'owner' ][ 'xchan_photo_mimetype' ], $item [ 'owner' ][ 'xchan_photo_m' ]);
2010-11-02 00:56:36 +00:00
2013-03-22 01:25:41 +00:00
if (( $item [ 'parent' ] != $item [ 'id' ]) || ( $item [ 'parent_mid' ] !== $item [ 'mid' ]) || (( $item [ 'thr_parent' ] !== '' ) && ( $item [ 'thr_parent' ] !== $item [ 'mid' ]))) {
$parent_item = (( $item [ 'thr_parent' ]) ? $item [ 'thr_parent' ] : $item [ 'parent_mid' ]);
2013-06-13 04:12:27 +00:00
$o .= '<thr:in-reply-to ref="' . xmlify ( $parent_item ) . '" type="text/html" href="' . xmlify ( $item [ 'plink' ]) . '" />' . " \r \n " ;
2012-06-23 13:04:56 +00:00
}
2010-11-02 00:56:36 +00:00
2013-03-22 01:25:41 +00:00
$o .= '<id>' . xmlify ( $item [ 'mid' ]) . '</id>' . " \r \n " ;
2010-11-02 00:56:36 +00:00
$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 " ;
2013-09-06 02:31:26 +00:00
$o .= '<content type="' . $type . '" >' . xmlify ( prepare_text ( $body , $item [ 'mimetype' ])) . '</content>' . " \r \n " ;
2013-06-13 04:12:27 +00:00
$o .= '<link rel="alternate" type="text/html" href="' . xmlify ( $item [ 'plink' ]) . '" />' . " \r \n " ;
2010-11-10 04:38:24 +00:00
if ( $item [ 'location' ]) {
2013-06-13 04:12:27 +00:00
$o .= '<zot:location>' . xmlify ( $item [ 'location' ]) . '</zot:location>' . " \r \n " ;
2010-11-10 04:38:24 +00:00
$o .= '<poco:address><poco:formatted>' . xmlify ( $item [ 'location' ]) . '</poco:formatted></poco:address>' . " \r \n " ;
}
2010-11-02 00:56:36 +00:00
if ( $item [ 'coord' ])
$o .= '<georss:point>' . xmlify ( $item [ 'coord' ]) . '</georss:point>' . " \r \n " ;
2013-06-13 04:12:27 +00:00
if (( $item [ 'item_private' ]) || strlen ( $item [ 'allow_cid' ]) || strlen ( $item [ 'allow_gid' ]) || strlen ( $item [ 'deny_cid' ]) || strlen ( $item [ 'deny_gid' ]))
$o .= '<zot:private>' . (( $item [ 'item_private' ]) ? $item [ 'item_private' ] : 1 ) . '</zot:private>' . " \r \n " ;
2010-12-08 04:47:53 +00:00
2011-05-23 01:40:00 +00:00
2011-06-21 02:08:40 +00:00
if ( $item [ 'app' ])
2011-08-29 02:22:27 +00:00
$o .= '<statusnet:notice_info local_id="' . $item [ 'id' ] . '" source="' . xmlify ( $item [ 'app' ]) . '" ></statusnet:notice_info>' . " \r \n " ;
2010-11-02 00:56:36 +00:00
$verb = construct_verb ( $item );
$o .= '<as:verb>' . xmlify ( $verb ) . '</as:verb>' . " \r \n " ;
2010-11-03 23:48:21 +00:00
$actobj = construct_activity_object ( $item );
2010-11-02 00:56:36 +00:00
if ( strlen ( $actobj ))
$o .= $actobj ;
2010-11-03 23:48:21 +00:00
$actarg = construct_activity_target ( $item );
if ( strlen ( $actarg ))
$o .= $actarg ;
2010-11-02 00:56:36 +00:00
2013-06-13 04:12:27 +00:00
// FIXME
// $tags = item_getfeedtags($item);
// if(count($tags)) {
// foreach($tags as $t) {
// $o .= '<category scheme="X-DFRN:' . xmlify($t[0]) . ':' . xmlify($t[1]) . '" term="' . xmlify($t[2]) . '" />' . "\r\n";
// }
// }
2011-04-06 00:41:02 +00:00
2013-06-13 04:12:27 +00:00
// FIXME
// $o .= item_getfeedattach($item);
2011-04-07 02:41:16 +00:00
2013-06-13 04:12:27 +00:00
// $mentioned = get_mentions($item,$tags);
// if($mentioned)
// $o .= $mentioned;
2010-11-02 00:56:36 +00:00
2010-12-25 02:32:23 +00:00
call_hooks ( 'atom_entry' , $o );
2010-11-02 00:56:36 +00:00
$o .= '</entry>' . " \r \n " ;
return $o ;
}
2011-04-06 00:41:02 +00:00
2012-07-07 22:20:24 +00:00
function fix_private_photos ( $s , $uid , $item = null , $cid = 0 ) {
2011-05-01 00:24:37 +00:00
$a = get_app ();
2012-05-28 04:01:58 +00:00
logger ( 'fix_private_photos' , LOGGER_DEBUG );
2012-05-29 23:44:02 +00:00
$site = substr ( $a -> get_baseurl (), strpos ( $a -> get_baseurl (), '://' ));
2011-05-01 00:24:37 +00:00
2012-07-07 22:20:24 +00:00
$orig_body = $s ;
$new_body = '' ;
2013-05-28 11:50:16 +00:00
$img_start = strpos ( $orig_body , '[zmg' );
2012-07-07 22:20:24 +00:00
$img_st_close = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start ), ']' ) : false );
2013-05-28 11:50:16 +00:00
$img_len = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start + $img_st_close + 1 ), '[/zmg]' ) : false );
2012-07-07 22:20:24 +00:00
while ( ( $img_st_close !== false ) && ( $img_len !== false ) ) {
$img_st_close ++ ; // make it point to AFTER the closing bracket
$image = substr ( $orig_body , $img_start + $img_st_close , $img_len );
2012-05-28 04:01:58 +00:00
logger ( 'fix_private_photos: found photo ' . $image , LOGGER_DEBUG );
2012-07-07 22:20:24 +00:00
2012-05-28 04:01:58 +00:00
if ( stristr ( $image , $site . '/photo/' )) {
2012-07-07 22:20:24 +00:00
// Only embed locally hosted photos
2012-05-28 04:01:58 +00:00
$replace = false ;
2011-05-01 00:24:37 +00:00
$i = basename ( $image );
$x = strpos ( $i , '-' );
2012-07-07 22:20:24 +00:00
2011-05-01 00:24:37 +00:00
if ( $x ) {
$res = substr ( $i , $x + 1 );
$i = substr ( $i , 0 , $x );
2012-10-02 01:02:11 +00:00
$r = q ( " SELECT * FROM `photo` WHERE `resource_id` = '%s' AND `scale` = %d AND `uid` = %d " ,
2011-05-01 00:24:37 +00:00
dbesc ( $i ),
intval ( $res ),
intval ( $uid )
);
if ( count ( $r )) {
2012-05-28 04:01:58 +00:00
// Check to see if we should replace this photo link with an embedded image
// 1. No need to do so if the photo is public
// 2. If there's a contact-id provided, see if they're in the access list
// for the photo. If so, embed it.
// 3. Otherwise, if we have an item, see if the item permissions match the photo
// permissions, regardless of order but first check to see if they're an exact
// match to save some processing overhead.
if ( has_permissions ( $r [ 0 ])) {
if ( $cid ) {
$recips = enumerate_permissions ( $r [ 0 ]);
if ( in_array ( $cid , $recips )) {
$replace = true ;
}
}
elseif ( $item ) {
if ( compare_permissions ( $item , $r [ 0 ]))
$replace = true ;
}
}
if ( $replace ) {
2012-07-07 22:20:24 +00:00
$data = $r [ 0 ][ 'data' ];
$type = $r [ 0 ][ 'type' ];
// If a custom width and height were specified, apply before embedding
2013-05-28 11:50:16 +00:00
if ( preg_match ( " / \ [zmg \ =([0-9]*)x([0-9]*) \ ]/is " , substr ( $orig_body , $img_start , $img_st_close ), $match )) {
2012-07-07 22:20:24 +00:00
logger ( 'fix_private_photos: scaling photo' , LOGGER_DEBUG );
$width = intval ( $match [ 1 ]);
$height = intval ( $match [ 2 ]);
2013-04-26 03:01:24 +00:00
$ph = photo_factory ( $data , $type );
2012-07-07 22:20:24 +00:00
if ( $ph -> is_valid ()) {
$ph -> scaleImage ( max ( $width , $height ));
$data = $ph -> imageString ();
$type = $ph -> getType ();
}
}
2012-05-28 23:51:52 +00:00
logger ( 'fix_private_photos: replacing photo' , LOGGER_DEBUG );
2012-07-07 22:20:24 +00:00
$image = 'data:' . $type . ';base64,' . base64_encode ( $data );
logger ( 'fix_private_photos: replaced: ' . $image , LOGGER_DATA );
2012-05-28 04:01:58 +00:00
}
2011-05-01 00:24:37 +00:00
}
}
}
2012-07-07 22:20:24 +00:00
2013-05-28 11:50:16 +00:00
$new_body = $new_body . substr ( $orig_body , 0 , $img_start + $img_st_close ) . $image . '[/zmg]' ;
$orig_body = substr ( $orig_body , $img_start + $img_st_close + $img_len + strlen ( '[/zmg]' ));
2012-07-07 22:20:24 +00:00
if ( $orig_body === false )
$orig_body = '' ;
2013-05-28 11:50:16 +00:00
$img_start = strpos ( $orig_body , '[zmg' );
2012-07-07 22:20:24 +00:00
$img_st_close = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start ), ']' ) : false );
2013-05-28 11:50:16 +00:00
$img_len = ( $img_start !== false ? strpos ( substr ( $orig_body , $img_start + $img_st_close + 1 ), '[/zmg]' ) : false );
2011-05-01 00:24:37 +00:00
}
2012-07-07 22:20:24 +00:00
2012-07-08 00:47:13 +00:00
$new_body = $new_body . $orig_body ;
2012-07-07 22:20:24 +00:00
return ( $new_body );
2011-05-01 00:24:37 +00:00
}
2012-05-28 04:01:58 +00:00
function has_permissions ( $obj ) {
if (( $obj [ 'allow_cid' ] != '' ) || ( $obj [ 'allow_gid' ] != '' ) || ( $obj [ 'deny_cid' ] != '' ) || ( $obj [ 'deny_gid' ] != '' ))
return true ;
return false ;
}
function compare_permissions ( $obj1 , $obj2 ) {
// first part is easy. Check that these are exactly the same.
if (( $obj1 [ 'allow_cid' ] == $obj2 [ 'allow_cid' ])
&& ( $obj1 [ 'allow_gid' ] == $obj2 [ 'allow_gid' ])
&& ( $obj1 [ 'deny_cid' ] == $obj2 [ 'deny_cid' ])
&& ( $obj1 [ 'deny_gid' ] == $obj2 [ 'deny_gid' ]))
return true ;
// This is harder. Parse all the permissions and compare the resulting set.
$recipients1 = enumerate_permissions ( $obj1 );
$recipients2 = enumerate_permissions ( $obj2 );
sort ( $recipients1 );
sort ( $recipients2 );
if ( $recipients1 == $recipients2 )
return true ;
return false ;
}
// returns an array of contact-ids that are allowed to see this object
function enumerate_permissions ( $obj ) {
require_once ( 'include/group.php' );
$allow_people = expand_acl ( $obj [ 'allow_cid' ]);
$allow_groups = expand_groups ( expand_acl ( $obj [ 'allow_gid' ]));
$deny_people = expand_acl ( $obj [ 'deny_cid' ]);
$deny_groups = expand_groups ( expand_acl ( $obj [ 'deny_gid' ]));
$recipients = array_unique ( array_merge ( $allow_people , $allow_groups ));
$deny = array_unique ( array_merge ( $deny_people , $deny_groups ));
$recipients = array_diff ( $recipients , $deny );
return $recipients ;
}
2011-05-01 00:24:37 +00:00
2011-04-06 00:41:02 +00:00
function item_getfeedtags ( $item ) {
2012-07-11 11:29:47 +00:00
$terms = get_terms_oftype ( $item [ 'term' ], array ( TERM_HASHTAG , TERM_MENTION ));
2011-04-06 00:41:02 +00:00
$ret = array ();
2012-07-11 11:29:47 +00:00
if ( count ( $terms )) {
foreach ( $terms as $term ) {
if ( $term [ 'type' ] == TERM_HASHTAG )
$ret [] = array ( '#' , $term [ 'url' ], $term [ 'term' ]);
else
$ret [] = array ( '@' , $term [ 'url' ], $term [ 'term' ]);
2011-04-06 00:41:02 +00:00
}
}
return $ret ;
}
2011-04-07 02:41:16 +00:00
function item_getfeedattach ( $item ) {
2011-04-07 03:03:06 +00:00
$ret = '' ;
2011-04-07 02:41:16 +00:00
$arr = explode ( ',' , $item [ 'attach' ]);
if ( count ( $arr )) {
foreach ( $arr as $r ) {
$matches = false ;
2011-08-04 02:18:58 +00:00
$cnt = preg_match ( '|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|' , $r , $matches );
2011-04-07 02:41:16 +00:00
if ( $cnt ) {
2011-04-07 03:36:24 +00:00
$ret .= '<link rel="enclosure" href="' . xmlify ( $matches [ 1 ]) . '" type="' . xmlify ( $matches [ 3 ]) . '" ' ;
2011-04-07 02:41:16 +00:00
if ( intval ( $matches [ 2 ]))
2011-08-04 02:18:58 +00:00
$ret .= 'length="' . intval ( $matches [ 2 ]) . '" ' ;
2011-04-07 02:41:16 +00:00
if ( $matches [ 4 ] !== ' ' )
2011-04-13 08:53:40 +00:00
$ret .= 'title="' . xmlify ( trim ( $matches [ 4 ])) . '" ' ;
2011-04-07 02:41:16 +00:00
$ret .= ' />' . " \r \n " ;
}
}
}
return $ret ;
}
2011-04-06 00:41:02 +00:00
2011-01-03 09:04:54 +00:00
2011-03-16 00:31:49 +00:00
function item_expire ( $uid , $days ) {
2012-05-29 06:24:10 +00:00
if (( ! $uid ) || ( $days < 1 ))
2011-03-16 00:31:49 +00:00
return ;
2012-05-29 06:24:10 +00:00
// $expire_network_only = save your own wall posts
// and just expire conversations started by others
2014-03-04 03:15:11 +00:00
// do not enable this until we can pass bulk delete messages through zot
// $expire_network_only = get_pconfig($uid,'expire','network_only');
$expire_network_only = 1 ;
2012-05-29 06:24:10 +00:00
2013-08-14 12:26:17 +00:00
$sql_extra = (( intval ( $expire_network_only )) ? " AND not (item_flags & " . intval ( ITEM_WALL ) . " ) " : " " );
2012-05-29 06:24:10 +00:00
2011-03-16 00:31:49 +00:00
$r = q ( " SELECT * FROM `item`
WHERE `uid` = % d
AND `created` < UTC_TIMESTAMP () - INTERVAL % d DAY
AND `id` = `parent`
2012-05-29 06:24:10 +00:00
$sql_extra
2014-03-04 03:15:11 +00:00
AND NOT ( item_flags & % d )
AND ( item_restrict = 0 ) " ,
2011-03-16 00:31:49 +00:00
intval ( $uid ),
2013-08-14 12:26:17 +00:00
intval ( $days ),
2014-03-04 03:15:11 +00:00
intval ( ITEM_RETAINED )
2011-03-16 00:31:49 +00:00
);
2013-08-14 12:26:17 +00:00
if ( ! $r )
2011-03-16 00:31:49 +00:00
return ;
2011-11-17 14:53:59 +00:00
2013-08-14 12:26:17 +00:00
$r = fetch_post_tags ( $r , true );
2011-03-16 00:31:49 +00:00
foreach ( $r as $item ) {
2012-03-27 07:54:34 +00:00
// don't expire filed items
2013-08-14 12:26:17 +00:00
$terms = get_terms_oftype ( $item [ 'term' ], TERM_FILE );
2014-03-04 03:15:11 +00:00
if ( $terms ) {
retain_item ( $item [ 'id' ]);
2012-03-27 07:54:34 +00:00
continue ;
2014-03-04 03:15:11 +00:00
}
2012-03-27 07:54:34 +00:00
2011-03-16 00:31:49 +00:00
// Only expire posts, not photos and photo comments
2014-03-04 03:15:11 +00:00
if ( $item [ 'resource_type' ] === 'photo' ) {
retain_item ( $item [ 'id' ]);
2011-03-16 00:31:49 +00:00
continue ;
2014-03-04 03:15:11 +00:00
}
if ( $item [ 'item_flags' ] & ITEM_STARRED ) {
retain_item ( $item [ 'id' ]);
2011-11-17 14:53:59 +00:00
continue ;
2014-03-04 03:15:11 +00:00
}
2011-11-17 14:53:59 +00:00
2012-05-05 14:05:32 +00:00
drop_item ( $item [ 'id' ], false );
2011-03-16 00:31:49 +00:00
}
2014-03-04 03:15:11 +00:00
// proc_run('php',"include/notifier.php","expire","$uid");
2011-11-17 14:53:59 +00:00
2011-06-11 03:39:46 +00:00
}
2014-03-04 03:15:11 +00:00
function retain_item ( $id ) {
$r = q ( " update item set item_flags = (item_flags | %d ) where id = %d limit 1 " ,
intval ( ITEM_RETAINED ),
intval ( $id )
);
}
2011-06-16 03:43:39 +00:00
function drop_items ( $items ) {
$uid = 0 ;
2012-04-17 11:33:50 +00:00
if ( ! local_user () && ! remote_user ())
2012-01-25 02:59:55 +00:00
return ;
2011-06-16 03:43:39 +00:00
if ( count ( $items )) {
foreach ( $items as $item ) {
$owner = drop_item ( $item , false );
if ( $owner && ! $uid )
$uid = $owner ;
}
}
// multiple threads may have been deleted, send an expire notification
if ( $uid )
proc_run ( 'php' , " include/notifier.php " , " expire " , " $uid " );
}
2013-01-25 00:44:10 +00:00
// Delete item with given item $id. $interactive means we're running interactively, and must check
// permissions to carry out this act. If it is non-interactive, we are deleting something at the
// system's request and do not check permission. This is very important to know.
2014-03-28 03:28:48 +00:00
// Some deletion requests (those coming from remote sites) must be staged.
// $stage = 0 => unstaged
// $stage = 1 => set deleted flag on the item and perform intial notifications
// $stage = 2 => perform low level delete at a later stage
function drop_item ( $id , $interactive = true , $stage = DROPITEM_NORMAL ) {
2011-06-16 03:43:39 +00:00
2014-06-26 23:24:53 +00:00
2011-06-16 03:43:39 +00:00
$a = get_app ();
// locate item to be deleted
2013-01-25 00:44:10 +00:00
$r = q ( " SELECT * FROM item WHERE id = %d LIMIT 1 " ,
2011-06-16 03:43:39 +00:00
intval ( $id )
);
2014-03-28 03:28:48 +00:00
if (( ! $r ) || (( $r [ 0 ][ 'item_restrict' ] & ITEM_DELETED ) && ( $stage === DROPITEM_NORMAL ))) {
2011-06-16 03:43:39 +00:00
if ( ! $interactive )
return 0 ;
notice ( t ( 'Item not found.' ) . EOL );
goaway ( $a -> get_baseurl () . '/' . $_SESSION [ 'return_url' ]);
}
$item = $r [ 0 ];
2013-01-25 00:44:10 +00:00
$ok_to_delete = false ;
2012-09-10 04:17:06 +00:00
2013-01-25 00:44:10 +00:00
// system deletion
if ( ! $interactive )
$ok_to_delete = true ;
2011-06-16 03:43:39 +00:00
2013-01-25 00:44:10 +00:00
// owner deletion
if ( local_user () && local_user () == $item [ 'uid' ])
$ok_to_delete = true ;
2013-01-23 12:50:57 +00:00
2013-01-25 00:44:10 +00:00
// author deletion
$observer = $a -> get_observer ();
if ( $observer && $observer [ 'xchan_hash' ] && ( $observer [ 'xchan_hash' ] === $item [ 'author_xchan' ]))
$ok_to_delete = true ;
2013-01-23 12:50:57 +00:00
2013-01-25 00:44:10 +00:00
if ( $ok_to_delete ) {
2012-05-05 14:05:32 +00:00
2013-11-27 07:10:10 +00:00
// set the deleted flag immediately on this item just in case the
// hook calls a remote process which loops. We'll delete it properly in a second.
$r = q ( " UPDATE item SET item_restrict = ( item_restrict | %d ) WHERE id = %d LIMIT 1 " ,
intval ( ITEM_DELETED ),
intval ( $item [ 'id' ])
);
2014-03-28 03:28:48 +00:00
$arr = array ( 'item' => $item , 'interactive' => $interactive , 'stage' => $stage );
2013-11-26 23:26:11 +00:00
call_hooks ( 'drop_item' , $arr );
2013-01-25 00:44:10 +00:00
$notify_id = intval ( $item [ 'id' ]);
2012-05-05 14:05:32 +00:00
2013-01-25 00:44:10 +00:00
$items = q ( " select * from item where parent = %d and uid = %d " ,
2012-05-05 14:05:32 +00:00
intval ( $item [ 'id' ]),
intval ( $item [ 'uid' ])
);
2013-01-25 00:44:10 +00:00
if ( $items ) {
foreach ( $items as $i )
2014-03-28 03:28:48 +00:00
delete_item_lowlevel ( $i , $stage );
2011-06-16 03:43:39 +00:00
}
2013-01-27 21:43:43 +00:00
else
2014-03-28 03:28:48 +00:00
delete_item_lowlevel ( $item , $stage );
2012-06-01 01:40:12 +00:00
2013-01-25 00:44:10 +00:00
if ( ! $interactive )
return 1 ;
2012-05-05 14:05:32 +00:00
2011-06-16 03:43:39 +00:00
// send the notification upstream/downstream as the case may be
2013-01-25 00:44:10 +00:00
// only send notifications to others if this is the owner's wall item.
2011-06-16 03:43:39 +00:00
2014-03-28 03:28:48 +00:00
if (( $item [ 'item_flags' ] & ITEM_WALL ) && ( $stage != DROPITEM_PHASE2 ))
2013-01-25 00:44:10 +00:00
proc_run ( 'php' , 'include/notifier.php' , 'drop' , $notify_id );
2011-06-16 03:43:39 +00:00
goaway ( $a -> get_baseurl () . '/' . $_SESSION [ 'return_url' ]);
2013-01-25 00:44:10 +00:00
2011-06-16 03:43:39 +00:00
}
else {
if ( ! $interactive )
return 0 ;
notice ( t ( 'Permission denied.' ) . EOL );
goaway ( $a -> get_baseurl () . '/' . $_SESSION [ 'return_url' ]);
}
2011-10-23 07:24:37 +00:00
}
2012-06-13 03:46:30 +00:00
2013-01-25 00:44:10 +00:00
// This function does not check for permission and does not send notifications and does not check recursion.
// It merely destroys all resources associated with an item.
// Please do not use without a suitable wrapper.
2014-03-28 03:28:48 +00:00
function delete_item_lowlevel ( $item , $stage = DROPITEM_NORMAL ) {
2013-01-25 00:44:10 +00:00
2014-03-28 03:28:48 +00:00
switch ( $stage ) {
case DROPITEM_PHASE2 :
$r = q ( " UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '',
changed = '%s' , edited = '%s' WHERE id = % d LIMIT 1 " ,
intval ( ITEM_PENDING_REMOVE ),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( $item [ 'id' ])
);
break ;
case DROPITEM_PHASE1 :
$r = q ( " UPDATE item SET item_restrict = ( item_restrict | %d ),
changed = '%s' , edited = '%s' WHERE id = % d LIMIT 1 " ,
intval ( ITEM_DELETED ),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( $item [ 'id' ])
);
break ;
case DROPITEM_NORMAL :
default :
$r = q ( " UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '',
changed = '%s' , edited = '%s' WHERE id = % d LIMIT 1 " ,
intval ( ITEM_DELETED ),
dbesc ( datetime_convert ()),
dbesc ( datetime_convert ()),
intval ( $item [ 'id' ])
);
break ;
}
2014-06-23 08:22:58 +00:00
// immediately remove any undesired profile likes.
q ( " delete from likes where iid = %d and channel_id = %d limit 1 " ,
intval ( $item [ 'id' ]),
intval ( $item [ 'uid' ])
);
2014-07-05 03:34:54 +00:00
// If item is a link to a photo/event resource, nuke all the associated photos/events
2013-01-25 00:44:10 +00:00
// This only applies to photos uploaded from the photos page. Photos inserted into a post do not
// generate a resource_id and therefore aren't intimately linked to the item.
if ( strlen ( $item [ 'resource_id' ])) {
if ( $item [ 'resource_type' ] === 'event' ) {
q ( " delete from event where event_hash = '%s' and uid = %d limit 1 " ,
dbesc ( $item [ 'resource_id' ]),
intval ( $item [ 'uid' ])
);
}
elseif ( $item [ 'resource_type' ] === 'photo' ) {
q ( " DELETE FROM `photo` WHERE `resource_id` = '%s' AND `uid` = %d " ,
dbesc ( $item [ 'resource_id' ]),
intval ( $item [ 'uid' ])
);
}
}
2014-07-05 03:34:54 +00:00
// network deletion request. Keep the message structure so that we can deliver delete notifications.
// Come back after several days (or perhaps a month) to do the lowlevel delete (DROPITEM_PHASE2).
if ( $stage == DROPITEM_PHASE1 )
return true ;
$r = q ( " delete from term where otype = %d and oid = %d limit 1 " ,
intval ( TERM_OBJ_POST ),
intval ( $item [ 'id' ])
);
2013-01-25 00:44:10 +00:00
q ( " delete from item_id where iid = %d and uid = %d limit 1 " ,
intval ( $item [ 'id' ]),
intval ( $item [ 'uid' ])
);
2013-02-18 23:15:55 +00:00
q ( " delete from term where oid = %d and otype = %d " ,
intval ( $item [ 'id' ]),
intval ( TERM_OBJ_POST )
);
// FIXME remove notifications for this item
2013-01-25 00:44:10 +00:00
return true ;
}
2012-06-13 03:46:30 +00:00
function first_post_date ( $uid , $wall = false ) {
2012-10-08 01:44:06 +00:00
$wall_sql = (( $wall ) ? sprintf ( " and item_flags & %d " , ITEM_WALL ) : " " );
$r = q ( " select id, created from item
where item_restrict = % d and uid = % d and id = parent $wall_sql
2012-06-13 03:46:30 +00:00
order by created asc limit 1 " ,
2012-10-08 01:44:06 +00:00
intval ( ITEM_VISIBLE ),
intval ( $uid )
2012-06-13 03:46:30 +00:00
);
2014-05-01 01:45:46 +00:00
if ( $r ) {
2012-06-13 04:39:39 +00:00
// logger('first_post_date: ' . $r[0]['id'] . ' ' . $r[0]['created'], LOGGER_DATA);
2012-06-13 05:52:34 +00:00
return substr ( datetime_convert ( '' , date_default_timezone_get (), $r [ 0 ][ 'created' ]), 0 , 10 );
2012-06-13 04:34:28 +00:00
}
2012-06-13 03:46:30 +00:00
return false ;
}
2014-05-01 01:45:46 +00:00
/**
* modified posted_dates () { below } to arrange the list in years , which we ' ll eventually
* use to make a menu of years with collapsible sub - menus for the months instead of the
* current flat list of all representative dates .
*/
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 ();
// If it's near the end of a long month, backup to the 28th so that in
// consecutive loops we'll always get a whole month difference.
if ( intval ( substr ( $dnow , 8 )) > 28 )
$dnow = substr ( $dnow , 0 , 8 ) . '28' ;
if ( intval ( substr ( $dthen , 8 )) > 28 )
$dnow = substr ( $dthen , 0 , 8 ) . '28' ;
$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 ;
}
2012-06-13 03:46:30 +00:00
function posted_dates ( $uid , $wall ) {
2012-06-13 05:52:34 +00:00
$dnow = datetime_convert ( '' , date_default_timezone_get (), 'now' , 'Y-m-d' );
2012-06-13 03:46:30 +00:00
$dthen = first_post_date ( $uid , $wall );
if ( ! $dthen )
return array ();
2012-06-13 05:52:34 +00:00
// If it's near the end of a long month, backup to the 28th so that in
// consecutive loops we'll always get a whole month difference.
if ( intval ( substr ( $dnow , 8 )) > 28 )
$dnow = substr ( $dnow , 0 , 8 ) . '28' ;
if ( intval ( substr ( $dthen , 8 )) > 28 )
$dnow = substr ( $dthen , 0 , 8 ) . '28' ;
2012-06-13 03:46:30 +00:00
$ret = array ();
2012-07-10 13:28:02 +00:00
// 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 )) {
2012-06-14 03:59:19 +00:00
$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' );
2012-06-13 03:46:30 +00:00
$str = day_translate ( datetime_convert ( '' , '' , $dnow , 'F Y' ));
$ret [] = array ( $str , $end_month , $start_month );
$dnow = datetime_convert ( '' , '' , $dnow . ' -1 month' , 'Y-m-d' );
}
return $ret ;
}
2013-02-11 08:20:14 +00:00
function fetch_post_tags ( $items , $link = false ) {
2012-07-11 02:28:02 +00:00
$tag_finder = array ();
2012-11-16 05:52:05 +00:00
if ( $items ) {
foreach ( $items as $item ) {
2013-01-03 00:28:47 +00:00
if ( is_array ( $item )) {
if ( array_key_exists ( 'item_id' , $item )) {
if ( ! in_array ( $item [ 'item_id' ], $tag_finder ))
$tag_finder [] = $item [ 'item_id' ];
}
else {
if ( ! in_array ( $item [ 'id' ], $tag_finder ))
$tag_finder [] = $item [ 'id' ];
}
2012-11-16 05:52:05 +00:00
}
}
}
2012-07-11 02:28:02 +00:00
$tag_finder_str = implode ( ', ' , $tag_finder );
2012-11-16 05:52:05 +00:00
2012-07-17 12:30:32 +00:00
if ( strlen ( $tag_finder_str )) {
$tags = q ( " select * from term where oid in ( %s ) and otype = %d " ,
dbesc ( $tag_finder_str ),
intval ( TERM_OBJ_POST )
);
}
2012-07-11 02:28:02 +00:00
2012-11-16 05:52:05 +00:00
2012-07-11 02:28:02 +00:00
for ( $x = 0 ; $x < count ( $items ); $x ++ ) {
2013-01-03 00:28:47 +00:00
if ( $tags ) {
2012-07-11 02:28:02 +00:00
foreach ( $tags as $t ) {
2013-02-11 08:20:14 +00:00
if (( $link ) && ( $t [ 'type' ] == TERM_MENTION ))
$t [ 'url' ] = chanlink_url ( $t [ 'url' ]);
2012-11-16 05:52:05 +00:00
if ( array_key_exists ( 'item_id' , $items [ $x ])) {
if ( $t [ 'oid' ] == $items [ $x ][ 'item_id' ]) {
if ( ! is_array ( $items [ $x ][ 'term' ]))
$items [ $x ][ 'term' ] = array ();
$items [ $x ][ 'term' ][] = $t ;
}
}
else {
if ( $t [ 'oid' ] == $items [ $x ][ 'id' ]) {
if ( ! is_array ( $items [ $x ][ 'term' ]))
$items [ $x ][ 'term' ] = array ();
$items [ $x ][ 'term' ][] = $t ;
}
2012-07-11 02:28:02 +00:00
}
}
}
}
return $items ;
}
2013-01-04 03:34:04 +00:00
2013-01-24 22:31:57 +00:00
function zot_feed ( $uid , $observer_xchan , $mindate ) {
2013-01-04 03:34:04 +00:00
2013-11-18 00:50:32 +00:00
2013-01-04 03:34:04 +00:00
$result = array ();
$mindate = datetime_convert ( 'UTC' , 'UTC' , $mindate );
if ( ! $mindate )
2014-09-09 03:35:15 +00:00
$mindate = NULL_DATE ;
2013-01-04 03:34:04 +00:00
2013-07-30 03:39:12 +00:00
$mindate = dbesc ( $mindate );
2013-11-18 00:50:32 +00:00
logger ( 'zot_feed: ' . $uid );
2013-01-24 22:31:57 +00:00
if ( ! perm_is_allowed ( $uid , $observer_xchan , 'view_stream' )) {
2013-11-18 00:50:32 +00:00
logger ( 'zot_feed: permission denied.' );
2013-01-04 03:34:04 +00:00
return $result ;
}
2014-03-27 02:13:26 +00:00
if ( ! is_sys_channel ( $uid )) {
require_once ( 'include/security.php' );
$sql_extra = item_permissions_sql ( $uid );
}
2013-01-04 03:34:04 +00:00
2014-09-09 03:35:15 +00:00
if ( $mindate != NULL_DATE ) {
2014-09-02 02:55:43 +00:00
$sql_extra .= " and ( created > ' $mindate ' or edited > ' $mindate ' ) " ;
2013-07-30 03:39:12 +00:00
$limit = " " ;
}
else
$limit = " limit 0, 50 " ;
2013-01-04 03:34:04 +00:00
2013-07-30 03:31:02 +00:00
$items = array ();
2013-01-04 03:34:04 +00:00
2014-03-26 23:09:07 +00:00
if ( is_sys_channel ( $uid )) {
2014-03-27 03:22:57 +00:00
require_once ( 'include/security.php' );
2014-04-18 03:03:28 +00:00
$r = q ( " SELECT distinct parent from item
WHERE uid != % d
and uid in ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) AND item_restrict = 0
2014-03-26 23:09:07 +00:00
AND ( item_flags & % d )
2014-03-27 02:13:26 +00:00
and item_private = 0 $sql_extra ORDER BY created ASC $limit " ,
2014-04-18 03:03:28 +00:00
intval ( $uid ),
2014-03-26 23:09:07 +00:00
intval ( ITEM_WALL )
);
}
else {
2014-04-18 03:03:28 +00:00
$r = q ( " SELECT distinct parent from item
WHERE uid = % d AND item_restrict = 0
2014-03-26 23:09:07 +00:00
AND ( item_flags & % d )
$sql_extra ORDER BY created ASC $limit " ,
intval ( $uid ),
intval ( ITEM_WALL )
);
}
2013-07-30 03:31:02 +00:00
2014-03-26 23:09:07 +00:00
if ( $r ) {
2014-04-18 03:03:28 +00:00
$parents_str = ids_to_querystr ( $r , 'parent' );
2014-04-18 05:06:35 +00:00
$sys_query = (( is_sys_channel ( $uid )) ? $sql_extra : '' );
2013-07-30 03:31:02 +00:00
$items = q ( " SELECT `item`.*, `item`.`id` AS `item_id` FROM `item`
2014-03-26 23:09:07 +00:00
WHERE `item` . `item_restrict` = 0
2014-04-18 05:06:35 +00:00
AND `item` . `parent` IN ( % s ) $sys_query " ,
2013-07-30 03:31:02 +00:00
dbesc ( $parents_str )
);
}
2013-01-04 03:34:04 +00:00
if ( $items ) {
xchan_query ( $items );
$items = fetch_post_tags ( $items );
2013-07-30 03:31:58 +00:00
require_once ( 'include/conversation.php' );
2013-07-30 03:31:02 +00:00
$items = conv_sort ( $items , 'ascending' );
2013-01-04 03:34:04 +00:00
}
2013-07-30 03:31:02 +00:00
else
$items = array ();
2013-01-04 03:34:04 +00:00
2014-04-18 05:06:35 +00:00
logger ( 'zot_feed: number items: ' . count ( $items ), LOGGER_DEBUG );
2013-01-04 03:34:04 +00:00
foreach ( $items as $item )
$result [] = encode_item ( $item );
return $result ;
}
2013-05-23 04:54:02 +00:00
2013-06-13 03:03:04 +00:00
function items_fetch ( $arr , $channel = null , $observer_hash = null , $client_mode = CLIENT_MODE_NORMAL , $module = 'network' ) {
2013-05-23 04:54:02 +00:00
$result = array ( 'success' => false );
2013-06-13 03:03:04 +00:00
$a = get_app ();
2013-05-23 04:54:02 +00:00
$sql_extra = '' ;
$sql_nets = '' ;
$sql_options = '' ;
$sql_extra2 = '' ;
$sql_extra3 = '' ;
2013-12-09 04:08:50 +00:00
$def_acl = '' ;
2013-05-24 01:50:27 +00:00
$item_uids = ' true ' ;
2014-01-25 02:50:47 +00:00
if ( $arr [ 'uid' ]) $uid = $arr [ 'uid' ];
2013-05-24 01:50:27 +00:00
if ( $channel ) {
$uid = $channel [ 'channel_id' ];
$uidhash = $channel [ 'channel_hash' ];
$item_uids = " item.uid = " . intval ( $uid ) . " " ;
}
2014-01-22 22:15:42 +00:00
2013-05-23 04:54:02 +00:00
if ( $arr [ 'star' ])
2013-06-13 03:03:04 +00:00
$sql_options .= " and (item_flags & " . intval ( ITEM_STARRED ) . " ) " ;
if ( $arr [ 'wall' ])
$sql_options .= " and (item_flags & " . intval ( ITEM_WALL ) . " ) " ;
2014-01-25 02:50:47 +00:00
2013-05-23 04:54:02 +00:00
$sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE (item_flags & " . intval ( ITEM_THREAD_TOP ) . " ) $sql_options ) " ;
2014-01-22 22:15:42 +00:00
if ( $arr [ 'since_id' ])
$sql_extra .= " and item.id > " . $since_id . " " ;
2013-12-09 04:08:50 +00:00
if ( $arr [ 'gid' ] && $uid ) {
2013-12-23 02:37:39 +00:00
$r = q ( " SELECT * FROM `groups` WHERE id = %d AND uid = %d LIMIT 1 " ,
2013-05-23 04:54:02 +00:00
intval ( $arr [ 'group' ]),
2013-05-24 01:50:27 +00:00
intval ( $uid )
2013-05-23 04:54:02 +00:00
);
if ( ! $r ) {
$result [ 'message' ] = t ( 'Collection not found.' );
return $result ;
}
2013-09-19 08:01:51 +00:00
$contact_str = '' ;
$contacts = group_get_members ( $group );
if ( $contacts ) {
foreach ( $contacts as $c ) {
if ( $contact_str )
$contact_str .= ',' ;
$contact_str .= " ' " . $c [ 'xchan' ] . " ' " ;
}
2013-05-23 04:54:02 +00:00
}
else {
2013-09-19 08:01:51 +00:00
$contact_str = ' 0 ' ;
2013-12-09 04:08:50 +00:00
$result [ 'message' ] = t ( 'Collection is empty.' );
return $result ;
2013-05-23 04:54:02 +00:00
}
2013-09-21 00:58:11 +00:00
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like ' " . protect_sprintf ( '%<' . dbesc ( $r [ 0 ][ 'hash' ]) . '>%' ) . " ' ) and id = parent and item_restrict = 0 ) " ;
2013-05-23 04:54:02 +00:00
2013-12-09 04:08:50 +00:00
$x = group_rec_byhash ( $uid , $r [ 0 ][ 'hash' ]);
$result [ 'headline' ] = sprintf ( t ( 'Collection: %s' ), $x [ 'name' ]);
2013-05-23 04:54:02 +00:00
}
2013-05-24 01:50:27 +00:00
elseif ( $arr [ 'cid' ] && $uid ) {
2013-05-23 04:54:02 +00:00
2013-09-29 09:47:36 +00:00
$r = q ( " SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and not ( abook_flags & " . intval ( ABOOK_FLAG_BLOCKED ) . " ) limit 1 " ,
2013-05-23 04:54:02 +00:00
intval ( $arr [ 'cid' ]),
2013-09-29 09:47:36 +00:00
intval ( local_user ())
2013-05-23 04:54:02 +00:00
);
if ( $r ) {
2013-06-28 04:40:56 +00:00
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval ( $arr [ 'uid' ]) . " AND ( author_xchan = ' " . dbesc ( $r [ 0 ][ 'abook_xchan' ]) . " ' or owner_xchan = ' " . dbesc ( $r [ 0 ][ 'abook_xchan' ]) . " ' ) and item_restrict = 0 ) " ;
2013-12-09 04:08:50 +00:00
$result [ 'headline' ] = sprintf ( t ( 'Connection: %s' ), $r [ 0 ][ 'xchan_name' ]);
2013-05-23 04:54:02 +00:00
}
else {
$result [ 'message' ] = t ( 'Connection not found.' );
return $result ;
}
}
if ( $arr [ 'datequery' ]) {
$sql_extra3 .= protect_sprintf ( sprintf ( " AND item.created <= '%s' " , dbesc ( datetime_convert ( date_default_timezone_get (), '' , $arr [ 'datequery' ]))));
}
if ( $arr [ 'datequery2' ]) {
$sql_extra3 .= protect_sprintf ( sprintf ( " AND item.created >= '%s' " , dbesc ( datetime_convert ( date_default_timezone_get (), '' , $arr [ 'datequery2' ]))));
}
if ( ! array_key_exists ( 'nouveau' , $arr )) {
2014-06-17 07:26:18 +00:00
$sql_extra2 = " AND item.parent = item.id " ;
2013-05-23 04:54:02 +00:00
$sql_extra3 = '' ;
}
if ( $arr [ 'search' ]) {
if ( strpos ( $arr [ 'search' ], '#' ) === 0 )
$sql_extra .= term_query ( 'item' , substr ( $arr [ 'search' ], 1 ), TERM_HASHTAG );
else
$sql_extra .= sprintf ( " AND item.body like '%s' " ,
dbesc ( protect_sprintf ( '%' . $arr [ 'search' ] . '%' ))
);
}
if ( strlen ( $arr [ 'file' ])) {
$sql_extra .= term_query ( 'item' , $arr [ 'files' ], TERM_FILE );
}
2013-05-24 01:50:27 +00:00
if ( $arr [ 'conv' ] && $channel ) {
2013-05-23 04:54:02 +00:00
$sql_extra .= sprintf ( " AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or ( item_flags & %d ))) " ,
2013-05-24 01:50:27 +00:00
dbesc ( protect_sprintf ( $uidhash )),
2013-05-23 04:54:02 +00:00
intval ( ITEM_MENTIONSME )
);
}
2014-01-25 23:51:10 +00:00
2013-05-24 01:50:27 +00:00
if (( $client_mode & CLIENT_MODE_UPDATE ) && ( ! ( $client_mode & CLIENT_MODE_LOAD ))) {
2013-05-23 04:54:02 +00:00
// only setup pagination on initial page view
$pager_sql = '' ;
}
else {
2013-05-24 01:50:27 +00:00
$itemspage = (( $channel ) ? get_pconfig ( $uid , 'system' , 'itemspage' ) : 20 );
2013-05-23 04:54:02 +00:00
$a -> set_pager_itemspage ((( intval ( $itemspage )) ? $itemspage : 20 ));
2013-05-24 01:50:27 +00:00
$pager_sql = sprintf ( " LIMIT %d, %d " , intval ( get_app () -> pager [ 'start' ]), intval ( get_app () -> pager [ 'itemspage' ]));
2013-05-23 04:54:02 +00:00
}
2014-01-25 23:51:10 +00:00
if ( isset ( $arr [ 'start' ]) && isset ( $arr [ 'records' ]))
$pager_sql = sprintf ( " LIMIT %d, %d " , intval ( $arr [ 'start' ]), intval ( $arr [ 'records' ]));
2013-05-23 04:54:02 +00:00
2014-03-18 23:50:46 +00:00
if ( array_key_exists ( 'cmin' , $arr ) || array_key_exists ( 'cmax' , $arr )) {
2014-06-17 07:26:18 +00:00
if (( $arr [ 'cmin' ] != 0 ) || ( $arr [ 'cmax' ] != 99 )) {
2013-05-23 04:54:02 +00:00
2014-06-17 07:26:18 +00:00
// Not everybody who shows up in the network stream will be in your address book.
// By default those that aren't are assumed to have closeness = 99; but this isn't
// recorded anywhere. So if cmax is 99, we'll open the search up to anybody in
// the stream with a NULL address book entry.
2013-05-23 04:54:02 +00:00
2014-03-18 23:50:46 +00:00
$sql_nets .= " AND " ;
2013-05-23 04:54:02 +00:00
2014-03-18 23:50:46 +00:00
if ( $arr [ 'cmax' ] == 99 )
$sql_nets .= " ( " ;
2013-05-23 04:54:02 +00:00
2014-03-18 23:50:46 +00:00
$sql_nets .= " ( abook.abook_closeness >= " . intval ( $arr [ 'cmin' ]) . " " ;
$sql_nets .= " AND abook.abook_closeness <= " . intval ( $arr [ 'cmax' ]) . " ) " ;
if ( $cmax == 99 )
$sql_nets .= " OR abook.abook_closeness IS NULL ) " ;
}
}
2013-05-23 04:54:02 +00:00
2013-05-24 01:50:27 +00:00
$simple_update = (( $client_mode & CLIENT_MODE_UPDATE ) ? " and ( item.item_flags & " . intval ( ITEM_UNSEEN ) . " ) " : '' );
if ( $client_mode & CLIENT_MODE_LOAD )
2013-05-23 04:54:02 +00:00
$simple_update = '' ;
$start = dba_timer ();
2013-06-14 00:53:16 +00:00
require_once ( 'include/security.php' );
2013-06-13 03:03:04 +00:00
$sql_extra .= item_permissions_sql ( $channel [ 'channel_id' ]);
2013-09-06 02:31:26 +00:00
if ( $arr [ 'pages' ])
$item_restrict = " AND (item_restrict & " . ITEM_WEBPAGE . " ) " ;
else
$item_restrict = " AND item_restrict = 0 " ;
2014-01-25 23:51:10 +00:00
if ( $arr [ 'nouveau' ] && ( $client_mode & CLIENT_MODE_LOAD ) && $channel ) {
2013-05-23 04:54:02 +00:00
// "New Item View" - show all items unthreaded in reverse created date order
2013-05-24 01:50:27 +00:00
$items = q ( " SELECT item.*, item.id AS item_id FROM item
2013-09-06 02:31:26 +00:00
WHERE $item_uids $item_restrict
2013-05-23 04:54:02 +00:00
$simple_update
$sql_extra $sql_nets
2013-05-24 01:50:27 +00:00
ORDER BY item . received DESC $pager_sql "
2013-05-23 04:54:02 +00:00
);
require_once ( 'include/items.php' );
xchan_query ( $items );
$items = fetch_post_tags ( $items , true );
}
2013-06-13 03:03:04 +00:00
else {
2013-05-23 04:54:02 +00:00
// Normal conversation view
2013-05-24 01:50:27 +00:00
if ( $arr [ 'order' ] === 'post' )
$ordering = " created " ;
2013-05-23 04:54:02 +00:00
else
2013-05-24 01:50:27 +00:00
$ordering = " commented " ;
2013-05-23 04:54:02 +00:00
2014-01-25 23:51:10 +00:00
if (( $client_mode & CLIENT_MODE_LOAD ) || ( $client_mode == CLIENT_MODE_NORMAL )) {
2013-05-23 04:54:02 +00:00
// Fetch a page full of parent items for this page
$r = q ( " SELECT distinct item.id AS item_id FROM item
left join abook on item . author_xchan = abook . abook_xchan
2013-09-06 02:31:26 +00:00
WHERE $item_uids $item_restrict
2013-05-23 04:54:02 +00:00
AND item . parent = item . id
and (( abook . abook_flags & % d ) = 0 or abook . abook_flags is null )
$sql_extra3 $sql_extra $sql_nets
ORDER BY item . $ordering DESC $pager_sql " ,
intval ( ABOOK_FLAG_BLOCKED )
);
2014-01-25 02:50:47 +00:00
2013-05-23 04:54:02 +00:00
}
else {
// update
$r = q ( " SELECT item.parent AS item_id FROM item
left join abook on item . author_xchan = abook . abook_xchan
2013-09-06 02:31:26 +00:00
WHERE $item_uids $item_restrict $simple_update
2013-05-23 04:54:02 +00:00
and (( abook . abook_flags & % d ) = 0 or abook . abook_flags is null )
$sql_extra3 $sql_extra $sql_nets " ,
intval ( ABOOK_FLAG_BLOCKED )
);
}
$first = dba_timer ();
// Then fetch all the children of the parents that are on this page
if ( $r ) {
$parents_str = ids_to_querystr ( $r , 'item_id' );
2014-08-22 22:51:48 +00:00
if ( $arr [ 'top' ])
$sql_extra = ' and id = parent ' . $sql_extra ;
2013-05-24 01:50:27 +00:00
$items = q ( " SELECT item.*, item.id AS item_id FROM item
2013-09-06 02:31:26 +00:00
WHERE $item_uids $item_restrict
2013-05-24 01:50:27 +00:00
AND item . parent IN ( % s )
2013-05-23 04:54:02 +00:00
$sql_extra " ,
dbesc ( $parents_str )
);
$second = dba_timer ();
xchan_query ( $items );
$third = dba_timer ();
$items = fetch_post_tags ( $items , true );
$fourth = dba_timer ();
2013-06-13 03:03:04 +00:00
require_once ( 'include/conversation.php' );
2013-05-23 04:54:02 +00:00
$items = conv_sort ( $items , $ordering );
//logger('items: ' . print_r($items,true));
}
else {
$items = array ();
}
2013-06-13 03:03:04 +00:00
if ( $parents_str && $arr [ 'mark_seen' ])
2013-05-23 04:54:02 +00:00
$update_unseen = ' AND parent IN ( ' . dbesc ( $parents_str ) . ' )' ;
2013-06-13 03:03:04 +00:00
// FIXME finish mark unseen sql
2013-05-23 04:54:02 +00:00
}
2013-06-13 03:03:04 +00:00
return $items ;
2013-09-25 19:43:21 +00:00
}
2014-01-04 21:44:43 +00:00
function update_remote_id ( $channel , $post_id , $webpage , $pagetitle , $namespace , $remote_id , $mid ) {
$page_type = '' ;
if ( $webpage & ITEM_WEBPAGE )
$page_type = 'WEBPAGE' ;
elseif ( $webpage & ITEM_BUILDBLOCK )
$page_type = 'BUILDBLOCK' ;
elseif ( $webpage & ITEM_PDL )
$page_type = 'PDL' ;
elseif ( $namespace && $remote_id ) {
$page_type = $namespace ;
$pagetitle = $remote_id ;
}
if ( $page_type ) {
// store page info as an alternate message_id so we can access it via
// https://sitename/page/$channelname/$pagetitle
// if no pagetitle was given or it couldn't be transliterated into a url, use the first
// sixteen bytes of the mid - which makes the link portable and not quite as daunting
// as the entire mid. If it were the post_id the link would be less portable.
$r = q ( " select * from item_id where iid = %d and uid = %d and service = '%s' limit 1 " ,
intval ( $post_id ),
intval ( $channel [ 'channel_id' ]),
dbesc ( $page_type )
);
if ( $r ) {
q ( " update item_id set sid = '%s' where id = %d limit 1 " ,
dbesc (( $pagetitle ) ? $pagetitle : substr ( $mid , 0 , 16 )),
intval ( $r [ 0 ][ 'id' ])
);
}
else {
q ( " insert into item_id ( iid, uid, sid, service ) values ( %d, %d, '%s','%s' ) " ,
intval ( $post_id ),
intval ( $channel [ 'channel_id' ]),
dbesc (( $pagetitle ) ? $pagetitle : substr ( $mid , 0 , 16 )),
dbesc ( $page_type )
);
}
}
}
2014-06-18 02:21:46 +00:00
/**
* change access control for item with message_id $mid and channel_id $uid
*/
function item_add_cid ( $xchan_hash , $mid , $uid ) {
$r = q ( " select id from item where mid = '%s' and uid = %d and allow_cid like '%s' " ,
dbesc ( $mid ),
intval ( $uid ),
dbesc ( '<' . $xchan_hash . '>' )
);
if ( ! $r ) {
$r = q ( " update item set allow_cid = concat(allow_cid,'%s') where mid = '%s' and uid = %d limit 1 " ,
dbesc ( '<' . $xchan_hash . '>' ),
dbesc ( $mid ),
intval ( $uid )
);
}
}
function item_remove_cid ( $xchan_hash , $mid , $uid ) {
$r = q ( " select allow_cid from item where mid = '%s' and uid = %d and allow_cid like '%s' " ,
dbesc ( $mid ),
intval ( $uid ),
dbesc ( '<' . $xchan_hash . '>' )
);
if ( $r ) {
$x = q ( " update item set allow_cid = '%s' where mid = '%s' and uid = %d limit 1 " ,
dbesc ( str_replace ( '<' . $xchan_hash . '>' , '' , $r [ 0 ][ 'allow_cid' ])),
dbesc ( $mid ),
intval ( $uid )
);
}
}