diff options
Diffstat (limited to 'include/items.php')
-rwxr-xr-x | include/items.php | 843 |
1 files changed, 440 insertions, 403 deletions
diff --git a/include/items.php b/include/items.php index 54dcf2b51..3e4805212 100755 --- a/include/items.php +++ b/include/items.php @@ -42,9 +42,8 @@ function collect_recipients($item, &$private_envelope) { // as that would allow the denied person to see the post by logging out. if((! $item['allow_cid']) && (! $item['allow_gid'])) { - $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d)>0 ", - intval($item['uid']), - intval(ABOOK_FLAG_SELF|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED) + $r = q("select * from abook where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 ", + intval($item['uid']) ); if($r) { @@ -82,9 +81,8 @@ function collect_recipients($item, &$private_envelope) { //$sys = get_sys_channel(); if(array_key_exists('public_policy',$item) && $item['public_policy'] !== 'self') { - $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)>0 ", - intval($item['uid']), - intval(ABOOK_FLAG_SELF|ABOOK_FLAG_PENDING|ABOOK_FLAG_ARCHIVED) + $r = q("select abook_xchan, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and abook_pending = 0 and abook_archived = 0 ", + intval($item['uid']) ); if($r) { @@ -192,20 +190,30 @@ function comments_are_now_closed($item) { return false; } +function item_normal() { + return " and item.item_hidden = 0 and item.item_type = 0 and item.item_deleted = 0 + and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0 + and item.item_blocked = 0 "; +} + /** * @brief * * This is a compatibility function primarily for plugins, because - * in future hubzilla (and later) DB schemas the definition of a - * normal item gets a bit more complicated. + * in earlier DB schemas this was a much simpler single integer compare * */ function is_item_normal($item) { - return((intval($item['item_restrict'])) ? false : true); -} + if(intval($item['item_hidden']) || intval($item['item_type']) || intval($item['item_deleted']) + || intval($item['item_unpublished']) || intval($item['item_delayed']) || intval($item['item_pending_remove']) + || intval($item['item_blocked'])) + return false; + + return true; +} /** * @brief @@ -264,6 +272,8 @@ function can_comment_on_post($observer_xchan, $item) { } if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red')) return true; + if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'diaspora')) + return true; if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],get_app()->get_hostname())) return true; @@ -396,12 +406,12 @@ function post_activity_item($arr) { if((($arr['parent']) && $arr['parent'] != $arr['id']) || (($arr['parent_mid']) && $arr['parent_mid'] != $arr['mid'])) $is_comment = true; - if(! x($arr,'item_flags')) { - if($is_comment) - $arr['item_flags'] = ITEM_ORIGIN; - else - $arr['item_flags'] = ITEM_ORIGIN | ITEM_WALL | ITEM_THREAD_TOP; - } + if(! array_key_exists('item_origin',$arr)) + $arr['item_origin'] = 1; + if(! array_key_exists('item_wall',$arr) && (! $is_comment)) + $arr['item_wall'] = 1; + if(! array_key_exists('item_thread_top',$arr) && (! $is_comment)) + $arr['item_thread_top'] = 1; $channel = get_app()->get_channel(); $observer = get_app()->get_observer(); @@ -428,17 +438,9 @@ function post_activity_item($arr) { 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; + $arr['item_verified'] = 1; } } - - logger('Encrypting local storage'); - $key = get_config('system','pubkey'); - $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED; - if($arr['title']) - $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key)); - if($arr['body']) - $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key)); } $arr['mid'] = ((x($arr,'mid')) ? $arr['mid'] : item_message_id()); @@ -460,7 +462,7 @@ function post_activity_item($arr) { $arr['comment_policy'] = map_scope($channel['channel_w_comment']); - if ((! $arr['plink']) && ($arr['item_flags'] & ITEM_THREAD_TOP)) { + if ((! $arr['plink']) && (intval($arr['item_thread_top']))) { $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; } @@ -495,6 +497,32 @@ function post_activity_item($arr) { return $ret; } + +function validate_item_elements($message,$arr) { + + $result = array('success' => false); + + if(! array_key_exists('created',$arr)) + $result['message'] = 'missing created, possible author/owner lookup failure'; + + if((! $arr['mid']) || (! $arr['parent_mid'])) + $result['message'] = 'missing message-id or parent message-id'; + + if(array_key_exists('flags',$message) && in_array('relay',$message['flags']) && $arr['mid'] === $arr['parent_mid']) + $result['message'] = 'relay set on top level post'; + + if(! $result['message']) + $result['success'] = true; + + return $result; + +} + + + + + + /** * @brief Generate an Atom feed. * @@ -807,7 +835,6 @@ function title_is_body($title, $body) { function get_item_elements($x,$allow_code = false) { - $arr = array(); if($allow_code) @@ -874,7 +901,8 @@ function get_item_elements($x,$allow_code = false) { if(array_key_exists('diaspora_signature',$x) && is_array($x['diaspora_signature'])) $x['diaspora_signature'] = json_encode($x['diaspora_signature']); - $arr['diaspora_meta'] = (($x['diaspora_signature']) ? json_encode(crypto_encapsulate($x['diaspora_signature'],$key)) : ''); + $arr['diaspora_meta'] = (($x['diaspora_signature']) ? $x['diaspora_signature'] : ''); + $arr['object'] = activity_sanitise($x['object']); $arr['target'] = activity_sanitise($x['target']); @@ -886,11 +914,12 @@ function get_item_elements($x,$allow_code = false) { $arr['item_flags'] = 0; if(array_key_exists('flags',$x) && in_array('consensus',$x['flags'])) - $arr['item_flags'] |= ITEM_CONSENSUS; + $arr['item_consensus'] = 1; + if(array_key_exists('flags',$x) && in_array('deleted',$x['flags'])) - $arr['item_restrict'] |= ITEM_DELETED; + $arr['item_deleted'] = 1; if(array_key_exists('flags',$x) && in_array('hidden',$x['flags'])) - $arr['item_restrict'] |= ITEM_HIDDEN; + $arr['item_hidden'] = 1; // 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 @@ -918,26 +947,13 @@ function get_item_elements($x,$allow_code = false) { dbesc($arr['author_xchan']) ); if($r && rsa_verify($x['body'],base64url_decode($arr['sig']),$r[0]['xchan_pubkey'])) - $arr['item_flags'] |= ITEM_VERIFIED; + $arr['item_verified'] = 1; 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. - - - if(intval($arr['item_private'])) { - $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED; - if($arr['title']) - $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key)); - if($arr['body']) - $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key)); - } - - if(array_key_exists('revision',$x)) { + // extended export encoding $arr['revision'] = $x['revision']; @@ -950,66 +966,77 @@ function get_item_elements($x,$allow_code = false) { $arr['resource_id'] = $x['resource_id']; $arr['resource_type'] = $x['resource_type']; $arr['attach'] = $x['attach']; + $arr['item_origin'] = $x['item_origin']; + $arr['item_unseen'] = $x['item_unseen']; + $arr['item_starred'] = $x['item_starred']; + $arr['item_uplink'] = $x['item_uplink']; + $arr['item_consensus'] = $x['item_consensus']; + $arr['item_wall'] = $x['item_wall']; + $arr['item_thread_top'] = $x['item_thread_top']; + $arr['item_notshown'] = $x['item_notshown']; + $arr['item_nsfw'] = $x['item_nsfw']; + // local only $arr['item_relay'] = $x['item_relay']; + $arr['item_mentionsme'] = $x['item_mentionsme']; + $arr['item_nocomment'] = $x['item_nocomment']; + // local only $arr['item_obscured'] = $x['item_obscured']; + // local only $arr['item_verified'] = $x['item_verified']; + $arr['item_retained'] = $x['item_retained']; + $arr['item_rss'] = $x['item_rss']; + $arr['item_deleted'] = $x['item_deleted']; + $arr['item_type'] = $x['item_type']; + $arr['item_hidden'] = $x['item_hidden']; + $arr['item_unpublished'] = $x['item_unpublished']; + $arr['item_delayed'] = $x['item_delayed']; + $arr['item_pending_remove'] = $x['item_pending_remove']; + $arr['item_blocked'] = $x['item_blocked']; + if(array_key_exists('item_flags',$x)) { + if($x['item_flags'] & 0x0004) + $arr['item_starred'] = 1; + if($x['item_flags'] & 0x0008) + $arr['item_uplink'] = 1; + if($x['item_flags'] & 0x0010) + $arr['item_consensus'] = 1; + if($x['item_flags'] & 0x0020) + $arr['item_wall'] = 1; + if($x['item_flags'] & 0x0040) + $arr['item_thread_top'] = 1; + if($x['item_flags'] & 0x0080) + $arr['item_notshown'] = 1; + if($x['item_flags'] & 0x0100) + $arr['item_nsfw'] = 1; + if($x['item_flags'] & 0x0400) + $arr['item_mentionsme'] = 1; + if($x['item_flags'] & 0x0800) + $arr['item_nocomment'] = 1; + if($x['item_flags'] & 0x4000) + $arr['item_retained'] = 1; + if($x['item_flags'] & 0x8000) + $arr['item_rss'] = 1; - if(! array_key_exists('item_origin',$x)) { - $arr['item_restrict'] = $x['item_restrict']; - $arr['item_flags'] = $x['item_flags']; } - - if(array_key_exists('item_origin',$x) && intval($x['item_origin'])) - $arr['item_flags'] |= ITEM_ORIGIN; - if(array_key_exists('item_unseen',$x) && intval($x['item_unseen'])) - $arr['item_flags'] |= ITEM_UNSEEN; - if(array_key_exists('item_starred',$x) && intval($x['item_starred'])) - $arr['item_flags'] |= ITEM_STARRED; - if(array_key_exists('item_uplink',$x) && intval($x['item_uplink'])) - $arr['item_flags'] |= ITEM_UPLINK; - if(array_key_exists('item_consensus',$x) && intval($x['item_consensus'])) - $arr['item_flags'] |= ITEM_CONSENSUS; - if(array_key_exists('item_wall',$x) && intval($x['item_wall'])) - $arr['item_flags'] |= ITEM_WALL; - if(array_key_exists('item_thread_top',$x) && intval($x['item_thread_top'])) - $arr['item_flags'] |= ITEM_THREAD_TOP; - if(array_key_exists('item_notshown',$x) && intval($x['item_notshown'])) - $arr['item_flags'] |= ITEM_NOTSHOWN; - if(array_key_exists('item_nsfw',$x) && intval($x['item_nsfw'])) - $arr['item_flags'] |= ITEM_NSFW; - if(array_key_exists('item_mentionsme',$x) && intval($x['item_mentionsme'])) - $arr['item_flags'] |= ITEM_MENTIONSME; - if(array_key_exists('item_nocomment',$x) && intval($x['item_nocomment'])) - $arr['item_flags'] |= ITEM_NOCOMMENT; - if(array_key_exists('item_retained',$x) && intval($x['item_retained'])) - $arr['item_flags'] |= ITEM_RETAINED; - if(array_key_exists('item_rss',$x) && intval($x['item_rss'])) - $arr['item_flags'] |= ITEM_RSS; - - - if(array_key_exists('item_deleted',$x)&& intval($x['item_deleted'])) - $arr['item_restrict'] |= ITEM_DELETED; - if(array_key_exists('item_unpublished',$x)&& intval($x['item_unpublished'])) - $arr['item_restrict'] |= ITEM_UNPUBLISHED; - if(array_key_exists('item_delayed',$x)&& intval($x['item_delayed'])) - $arr['item_restrict'] |= ITEM_DELAYED_PUBLISH; - if(array_key_exists('item_pending_remove',$x)&& intval($x['item_pending_remove'])) - $arr['item_restrict'] |= ITEM_PENDING_REMOVE; - if(array_key_exists('item_type',$x)) { - switch(intval($x['item_type'])) { - case 1: - $arr['item_restrict'] |= ITEM_BUILDBLOCK; - break; - case 2: - $arr['item_restrict'] |= ITEM_PDL; - break; - case 3: - $arr['item_restrict'] |= ITEM_WEBPAGE; - break; - case 4: - $arr['item_restrict'] |= ITEM_BUG; - break; - case 0: - default: - break; - } + if(array_key_exists('item_restrict',$x)) { + if($x['item_restrict'] & 0x0001) + $arr['item_hidden'] = 1; + if($x['item_restrict'] & 0x0002) + $arr['item_blocked'] = 1; + if($x['item_restrict'] & 0x0010) + $arr['item_deleted'] = 1; + if($x['item_restrict'] & 0x0020) + $arr['item_unpublished'] = 1; + if($x['item_restrict'] & 0x0040) + $arr['item_type'] = ITEM_TYPE_WEBPAGE; + if($x['item_restrict'] & 0x0080) + $arr['item_delayed'] = 1; + if($x['item_restrict'] & 0x0100) + $arr['item_type'] = ITEM_TYPE_BLOCK; + if($x['item_restrict'] & 0x0200) + $arr['item_type'] = ITEM_TYPE_PDL; + if($x['item_restrict'] & 0x0400) + $arr['item_type'] = ITEM_TYPE_BUG; + if($x['item_restrict'] & 0x0800) + $arr['item_pending_remove'] = 1; + if($x['item_restrict'] & 0x1000) + $arr['item_type'] = ITEM_TYPE_DOC; } } @@ -1104,7 +1131,7 @@ function import_author_rss($x) { if($r && $x['photo']) { - $photos = import_profile_photo($x['photo']['src'],$x['url']); + $photos = import_xchan_photo($x['photo']['src'],$x['url']); if($photos) { /** @bug $arr is undefined in this SQL query */ @@ -1149,7 +1176,7 @@ function import_author_unknown($x) { ); if($r && $x['photo']) { - $photos = import_profile_photo($x['photo']['src'],$x['url']); + $photos = import_xchan_photo($x['photo']['src'],$x['url']); if($photos) { /** @bug $arr is undefined in this SQL query */ @@ -1193,7 +1220,7 @@ function encode_item($item,$mirror = false) { $key = get_config('system','prvkey'); - if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED)) { + if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) { if($item['title']) $item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key); if($item['body']) @@ -1216,67 +1243,30 @@ function encode_item($item,$mirror = false) { $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['item_unseen'] = $item['item_unseen']; $x['attach'] = $item['attach']; - if(array_key_exists('item_starred',$item) && intval($item['item_starred'])) - $x['item_flags'] |= ITEM_STARRED; - if(array_key_exists('item_uplink',$item) && intval($item['item_uplink'])) - $x['item_flags'] |= ITEM_UPLINK; - if(array_key_exists('item_consensus',$item) && intval($item['item_consensus'])) - $x['item_flags'] |= ITEM_CONSENSUS; - if(array_key_exists('item_wall',$item) && intval($item['item_wall'])) - $x['item_flags'] |= ITEM_WALL; - if(array_key_exists('item_thread_top',$item) && intval($item['item_thread_top'])) - $x['item_flags'] |= ITEM_THREAD_TOP; - if(array_key_exists('item_notshown',$item) && intval($item['item_notshown'])) - $x['item_flags'] |= ITEM_NOTSHOWN; - if(array_key_exists('item_nsfw',$item) && intval($item['item_nsfw'])) - $x['item_flags'] |= ITEM_NSFW; - if(array_key_exists('item_mentionsme',$item) && intval($item['item_mentionsme'])) - $x['item_flags'] |= ITEM_MENTIONSME; - if(array_key_exists('item_nocomment',$item) && intval($item['item_nocomment'])) - $x['item_flags'] |= ITEM_NOCOMMENT; - if(array_key_exists('item_retained',$item) && intval($item['item_retained'])) - $x['item_flags'] |= ITEM_RETAINED; - if(array_key_exists('item_rss',$item) && intval($item['item_rss'])) - $x['item_flags'] |= ITEM_RSS; - if(array_key_exists('item_deleted',$item) && intval($item['item_deleted'])) - $x['item_restrict'] |= ITEM_DELETED; - if(array_key_exists('item_hidden',$item) && intval($item['item_hidden'])) - $x['item_restrict'] |= ITEM_HIDDEN; - if(array_key_exists('item_unpublished',$item) && intval($item['item_unpublished'])) - $x['item_restrict'] |= ITEM_UNPUBLISHED; - if(array_key_exists('item_delayed',$item) && intval($item['item_delayed'])) - $x['item_restrict'] |= ITEM_DELAYED_PUBLISH; - if(array_key_exists('item_pending_remove',$item) && intval($item['item_pending_remove'])) - $x['item_restrict'] |= ITEM_PENDING_REMOVE; - if(array_key_exists('item_blocked',$item) && intval($item['item_blocked'])) - $x['item_flags'] |= ITEM_BLOCKED; - if(array_key_exists('item_',$item) && intval($item['item_'])) - $x['item_flags'] |= ITEM_; - if(array_key_exists('item_type',$item) && intval($item['item_type'])) { - switch(intval($item['item_type'])) { - case 1: - $x['item_restrict'] |= ITEM_BUILDBLOCK; - break; - case 2: - $x['item_restrict'] |= ITEM_PDL; - break; - case 3: - $x['item_restrict'] |= ITEM_WEBPAGE; - break; - case 4: - $x['item_restrict'] |= ITEM_BUG; - break; - case 5: - $x['item_restrict'] |= ITEM_DOC; - break; - default: - break; - } - } + $x['item_origin'] = $item['item_origin']; + $x['item_unseen'] = $item['item_unseen']; + $x['item_starred'] = $item['item_starred']; + $x['item_uplink'] = $item['item_uplink']; + $x['item_consensus'] = $item['item_consensus']; + $x['item_wall'] = $item['item_wall']; + $x['item_thread_top'] = $item['item_thread_top']; + $x['item_notshown'] = $item['item_notshown']; + $x['item_nsfw'] = $item['item_nsfw']; + $x['item_relay'] = $item['item_relay']; + $x['item_mentionsme'] = $item['item_mentionsme']; + $x['item_nocomment'] = $item['item_nocomment']; + $x['item_obscured'] = $item['item_obscured']; + $x['item_verified'] = $item['item_verified']; + $x['item_retained'] = $item['item_retained']; + $x['item_rss'] = $item['item_rss']; + $x['item_deleted'] = $item['item_deleted']; + $x['item_type'] = $item['item_type']; + $x['item_hidden'] = $item['item_hidden']; + $x['item_unpublished'] = $item['item_unpublished']; + $x['item_delayed'] = $item['item_delayed']; + $x['item_pending_remove'] = $item['item_pending_remove']; + $x['item_blocked'] = $item['item_blocked']; } @@ -1317,7 +1307,7 @@ function encode_item($item,$mirror = false) { $x['public_scope'] = $scope; - if($item['item_flags'] & ITEM_NOCOMMENT) + if($item['item_nocomment']) $x['comment_scope'] = 'none'; else $x['comment_scope'] = $c_scope; @@ -1325,9 +1315,17 @@ function encode_item($item,$mirror = false) { if($item['term']) $x['tags'] = encode_item_terms($item['term'],$mirror); - if($item['diaspora_meta']) - $x['diaspora_signature'] = crypto_unencapsulate(json_decode($item['diaspora_meta'],true),$key); - + if($item['diaspora_meta']) { + $z = json_decode($item['diaspora_meta'],true); + if($z) { + if(is_array($z) && array_key_exists('iv',$z)) + $x['diaspora_signature'] = crypto_unencapsulate($z,$key); + else + $x['diaspora_signature'] = $z; + if(! is_array($z)) + logger('encode_item: diaspora meta is not an array: ' . print_r($z,true)); + } + } logger('encode_item: ' . print_r($x,true), LOGGER_DATA); return $x; @@ -1407,7 +1405,7 @@ function encode_item_xchan($xchan) { return $ret; } -function encode_item_terms($terms) { +function encode_item_terms($terms,$mirror = false) { $ret = array(); $allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK ); @@ -1545,17 +1543,17 @@ function encode_item_flags($item) { $ret = array(); - if($item['item_restrict'] & ITEM_DELETED) + if(intval($item['item_deleted'])) $ret[] = 'deleted'; - if($item['item_restrict'] & ITEM_HIDDEN) + if(intval($item['item_hidden'])) $ret[] = 'hidden'; - if($item['item_flags'] & ITEM_THREAD_TOP) + if(intval($item['item_thread_top'])) $ret[] = 'thread_parent'; - if($item['item_flags'] & ITEM_NSFW) + if(intval($item['item_nsfw'])) $ret[] = 'nsfw'; - if($item['item_flags'] & ITEM_CONSENSUS) + if(intval($item['item_consensus'])) $ret[] = 'consensus'; - if($item['item_private']) + if(intval($item['item_private'])) $ret[] = 'private'; return $ret; @@ -1566,12 +1564,11 @@ function encode_mail($item,$extended = false) { $x['type'] = 'mail'; $x['encoding'] = 'zot'; - if(array_key_exists('mail_flags',$item) && ($item['mail_flags'] & MAIL_OBSCURED)) { - $key = get_config('system','prvkey'); + if(array_key_exists('mail_obscured',$item) && intval($item['mail_obscured'])) { if($item['title']) - $item['title'] = crypto_unencapsulate(json_decode_plus($item['title']),$key); + $item['title'] = base64url_decode(str_rot47($item['title'])); if($item['body']) - $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key); + $item['body'] = base64url_decode(str_rot47($item['body'])); } $x['message_id'] = $item['mid']; @@ -1589,7 +1586,7 @@ function encode_mail($item,$extended = false) { $x['flags'] = array(); - if($item['mail_flags'] & MAIL_RECALLED) { + if(intval($item['mail_recalled'])) { $x['flags'][] = 'recalled'; $x['title'] = ''; $x['body'] = ''; @@ -1597,13 +1594,13 @@ function encode_mail($item,$extended = false) { if($extended) { $x['conv_guid'] = $item['conv_guid']; - if($item['mail_flags'] & MAIL_DELETED) + if(intval($item['mail_deleted'])) $x['flags'][] = 'deleted'; - if($item['mail_flags'] & MAIL_REPLIED) + if(intval($item['mail_replied'])) $x['flags'][] = 'replied'; - if($item['mail_flags'] & MAIL_ISREPLY) + if(intval($item['mail_isreply'])) $x['flags'][] = 'isreply'; - if($item['mail_flags'] & MAIL_SEEN) + if(intval($item['mail_seen'])) $x['flags'][] = 'seen'; } @@ -1619,6 +1616,8 @@ function get_mail_elements($x) { $arr['body'] = (($x['body']) ? htmlspecialchars($x['body'], ENT_COMPAT,'UTF-8',false) : ''); $arr['title'] = (($x['title'])? htmlspecialchars($x['title'],ENT_COMPAT,'UTF-8',false) : ''); + $arr['conv_guid'] = (($x['conv_guid'])? htmlspecialchars($x['conv_guid'],ENT_COMPAT,'UTF-8',false) : ''); + $arr['created'] = datetime_convert('UTC','UTC',$x['created']); if((! array_key_exists('expires',$x)) || ($x['expires'] === NULL_DATE)) $arr['expires'] = NULL_DATE; @@ -1629,34 +1628,35 @@ function get_mail_elements($x) { if($x['flags'] && is_array($x['flags'])) { if(in_array('recalled',$x['flags'])) { - $arr['mail_flags'] |= MAIL_RECALLED; + $arr['mail_recalled'] = 1; } if(in_array('replied',$x['flags'])) { - $arr['mail_flags'] |= MAIL_REPLIED; + $arr['mail_replied'] = 1; } if(in_array('isreply',$x['flags'])) { - $arr['mail_flags'] |= MAIL_ISREPLY; + $arr['mail_isreply'] = 1; } if(in_array('seen',$x['flags'])) { - $arr['mail_flags'] |= MAIL_SEEN; + $arr['mail_seen'] = 1; } if(in_array('deleted',$x['flags'])) { - $arr['mail_flags'] |= MAIL_DELETED; + $arr['mail_deleted'] = 1; } } $key = get_config('system','pubkey'); - $arr['mail_flags'] |= MAIL_OBSCURED; - $arr['body'] = htmlspecialchars($arr['body'],ENT_COMPAT,'UTF-8',false); - if($arr['body']) - $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key)); - $arr['title'] = htmlspecialchars($arr['title'],ENT_COMPAT,'UTF-8',false); - if($arr['title']) - $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key)); + $arr['mail_obscured'] = 1; + if($arr['body']) { + $arr['body'] = str_rot47(base64url_encode($arr['body'])); + } + if($arr['title']) { + $arr['title'] = str_rot47(base64url_encode($arr['title'])); + } if($arr['created'] > datetime_convert()) $arr['created'] = datetime_convert(); + $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) : ''); @@ -1735,7 +1735,7 @@ function get_atom_elements($feed, $item, &$author) { $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $res['plink'] = unxmlify($item->get_link(0)); - $res['item_flags'] = ITEM_RSS; + $res['item_rss'] = 1; // removing the content of the title if its identically to the body @@ -2175,11 +2175,11 @@ function item_store($arr, $allow_exec = false) { // 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", + $l = q("select item_type 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))) + if((! $l) || (! ($l[0]['item_type'] != ITEM_TYPE_PDL))) unset($arr['layout_mid']); } @@ -2208,12 +2208,13 @@ function item_store($arr, $allow_exec = false) { $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 ); + $arr['item_wall'] = ((x($arr,'item_wall')) ? intval($arr['item_wall']) : 0 ); + $arr['item_type'] = ((x($arr,'item_type')) ? intval($arr['item_type']) : 0 ); // 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)) { + if((! array_key_exists('item_obscured',$arr)) || $arr['item_obscured'] == 0) { $arr['lang'] = detect_language($arr['body']); // apply the input filter here - if it is obscured it has been filtered already @@ -2223,7 +2224,7 @@ function item_store($arr, $allow_exec = false) { $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; + $arr['item_verified'] = 1; } } @@ -2239,14 +2240,6 @@ function item_store($arr, $allow_exec = false) { } $arr = $translate['item']; } - if($arr['item_private']) { - $key = get_config('system','pubkey'); - $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED; - if($arr['title']) - $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key)); - if($arr['body']) - $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key)); - } } if((x($arr,'object')) && is_array($arr['object'])) { @@ -2288,16 +2281,16 @@ function item_store($arr, $allow_exec = false) { $arr['plink'] = ((x($arr,'plink')) ? notags(trim($arr['plink'])) : ''); $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : ''); $arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : ''); - $arr['item_restrict'] = ((x($arr,'item_restrict')) ? intval($arr['item_restrict']) : 0 ); $arr['public_policy'] = ((x($arr,'public_policy')) ? notags(trim($arr['public_policy'])) : '' ); $arr['comment_policy'] = ((x($arr,'comment_policy')) ? notags(trim($arr['comment_policy'])) : 'contacts' ); + + if(! array_key_exists('item_unseen',$arr)) + $arr['item_unseen'] = 1; - $arr['item_unseen'] = ((array_key_exists('item_unseen',$arr)) ? intval($arr['item_unseen']) : 1); - - if($arr['comment_policy'] == 'none') - $arr['item_flags'] = $arr['item_flags'] | ITEM_NOCOMMENT; + if((! array_key_exists('item_nocomment',$arr)) && ($arr['comment_policy'] == 'none')) + $arr['item_nocomment'] = 1; // handle time travelers // Allow a bit of fudge in case somebody just has a slightly slow/fast clock @@ -2305,7 +2298,7 @@ function item_store($arr, $allow_exec = false) { $d1 = new DateTime('now +10 minutes', new DateTimeZone('UTC')); $d2 = new DateTime($arr['created'] . '+00:00'); if($d2 > $d1) - $arr['item_restrict'] = $arr['item_restrict'] | ITEM_DELAYED_PUBLISH; + $arr['item_delayed'] = 1; $arr['llink'] = z_root() . '/display/' . $arr['mid']; @@ -2321,7 +2314,7 @@ function item_store($arr, $allow_exec = false) { $deny_gid = $arr['deny_gid']; $public_policy = $arr['public_policy']; $comments_closed = $arr['comments_closed']; - $arr['item_flags'] = $arr['item_flags'] | ITEM_THREAD_TOP; + $arr['item_thread_top'] = 1; } else { @@ -2371,7 +2364,7 @@ function item_store($arr, $allow_exec = false) { } $parent_id = $r[0]['id']; - $parent_deleted = $r[0]['item_restrict'] & ITEM_DELETED; + $parent_deleted = $r[0]['item_deleted']; $allow_cid = $r[0]['allow_cid']; $allow_gid = $r[0]['allow_gid']; $deny_cid = $r[0]['deny_cid']; @@ -2379,8 +2372,8 @@ function item_store($arr, $allow_exec = false) { $public_policy = $r[0]['public_policy']; $comments_closed = $r[0]['comments_closed']; - if($r[0]['item_flags'] & ITEM_WALL) - $arr['item_flags'] = $arr['item_flags'] | ITEM_WALL; + if(intval($r[0]['item_wall'])) + $arr['item_wall'] = 1; // An uplinked comment might arrive with a downstream owner. // Fix it. @@ -2399,7 +2392,7 @@ function item_store($arr, $allow_exec = false) { // 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. - if((intval($r[0]['item_flags']) & ITEM_UPLINK) && (! $r[0]['item_private'])) + if(intval($r[0]['item_uplink']) && (! $r[0]['item_private'])) $arr['item_private'] = 0; } else { @@ -2410,7 +2403,7 @@ function item_store($arr, $allow_exec = false) { } if($parent_deleted) - $arr['item_restrict'] = $arr['item_restrict'] | ITEM_DELETED; + $arr['item_deleted'] = 1; $r = q("SELECT `id` FROM `item` WHERE `mid` = '%s' AND `uid` = %d LIMIT 1", dbesc($arr['mid']), @@ -2522,10 +2515,9 @@ function item_store($arr, $allow_exec = false) { // update the commented timestamp on the parent - $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and not ( item_restrict & %d )>0 ", + $z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ", dbesc($arr['parent_mid']), - intval($arr['uid']), - intval(ITEM_DELAYED_PUBLISH) + intval($arr['uid']) ); q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d", @@ -2540,7 +2532,7 @@ function item_store($arr, $allow_exec = false) { // so that we have an item in the DB that's marked deleted and won't store a fresh post // that isn't aware that we were already told to delete it. - if(! ($arr['item_restrict'] & ITEM_DELETED)) { + if(! intval($arr['item_deleted'])) { send_status_notifications($current_post,$arr); tag_deliver($arr['uid'],$current_post); } @@ -2587,17 +2579,8 @@ function item_store_update($arr,$allow_exec = false) { // override the unseen flag with the original - if(intval($arr['item_flags'])) - $arr['item_unseen'] = 0; - - if($orig[0]['item_flags'] & ITEM_VERIFIED) - $orig[0]['item_flags'] = $orig[0]['item_flags'] ^ ITEM_VERIFIED; + $arr['item_unseen'] = $orig[0]['item_unseen']; - if($orig[0]['item_flags'] & ITEM_OBSCURED) - $orig[0]['item_flags'] = $orig[0]['item_flags'] ^ ITEM_OBSCURED; - - $arr['item_flags'] = intval($arr['item_flags']) | $orig[0]['item_flags']; - $arr['item_restrict'] = intval($arr['item_restrict']) | $orig[0]['item_restrict']; if(array_key_exists('edit',$arr)) unset($arr['edit']); @@ -2610,19 +2593,20 @@ function item_store_update($arr,$allow_exec = false) { return $ret; } - if(! ($arr['item_flags'] & ITEM_OBSCURED)) { + if((! array_key_exists('item_obscured', $arr)) || $arr['item_obscured'] == 0) { $arr['lang'] = detect_language($arr['body']); - // apply the input filter here - if it is obscured it has been filtered already - $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype'])); - if(local_channel() && (! $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; - } - } + // apply the input filter here - if it is obscured it has been filtered already + $arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype'])); + + if(local_channel() && (! $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_verified'] = 1; + } + } $allowed_languages = get_pconfig($arr['uid'],'system','allowed_languages'); @@ -2636,14 +2620,6 @@ function item_store_update($arr,$allow_exec = false) { } $arr = $translate['item']; } - if($arr['item_private']) { - $key = get_config('system','pubkey'); - $arr['item_flags'] = $arr['item_flags'] | ITEM_OBSCURED; - if($arr['title']) - $arr['title'] = json_encode(crypto_encapsulate($arr['title'],$key)); - if($arr['body']) - $arr['body'] = json_encode(crypto_encapsulate($arr['body'],$key)); - } } if((x($arr,'object')) && is_array($arr['object'])) { @@ -2701,13 +2677,38 @@ function item_store_update($arr,$allow_exec = false) { $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']); - $arr['title'] = ((array_key_exists('title',$arr)) ? trim($arr['title']) : $orig[0]['title']); - $arr['body'] = ((array_key_exists('body',$arr)) ? trim($arr['body']) : $orig[0]['body']); + $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']) : ''); + $arr['html'] = ((array_key_exists('html',$arr) && strlen($arr['html'])) ? trim($arr['html']) : ''); + + $arr['attach'] = ((array_key_exists('attach',$arr)) ? notags(trim($arr['attach'])) : $orig[0]['attach']); + $arr['app'] = ((array_key_exists('app',$arr)) ? notags(trim($arr['app'])) : $orig[0]['app']); + + $arr['item_origin'] = ((array_key_exists('item_origin',$arr)) ? intval($arr['item_origin']) : $orig[0]['item_origin'] ); + $arr['item_unseen'] = ((array_key_exists('item_unseen',$arr)) ? intval($arr['item_unseen']) : $orig[0]['item_unseen'] ); + $arr['item_starred'] = ((array_key_exists('item_starred',$arr)) ? intval($arr['item_starred']) : $orig[0]['item_starred'] ); + $arr['item_uplink'] = ((array_key_exists('item_uplink',$arr)) ? intval($arr['item_uplink']) : $orig[0]['item_uplink'] ); + $arr['item_consensus'] = ((array_key_exists('item_consensus',$arr)) ? intval($arr['item_consensus']) : $orig[0]['item_consensus'] ); + $arr['item_wall'] = ((array_key_exists('item_wall',$arr)) ? intval($arr['item_wall']) : $orig[0]['item_wall'] ); + $arr['item_thread_top'] = ((array_key_exists('item_thread_top',$arr)) ? intval($arr['item_thread_top']) : $orig[0]['item_thread_top'] ); + $arr['item_notshown'] = ((array_key_exists('item_notshown',$arr)) ? intval($arr['item_notshown']) : $orig[0]['item_notshown'] ); + $arr['item_nsfw'] = ((array_key_exists('item_nsfw',$arr)) ? intval($arr['item_nsfw']) : $orig[0]['item_nsfw'] ); + $arr['item_relay'] = ((array_key_exists('item_relay',$arr)) ? intval($arr['item_relay']) : $orig[0]['item_relay'] ); + $arr['item_mentionsme'] = ((array_key_exists('item_mentionsme',$arr)) ? intval($arr['item_mentionsme']) : $orig[0]['item_mentionsme'] ); + $arr['item_nocomment'] = ((array_key_exists('item_nocomment',$arr)) ? intval($arr['item_nocomment']) : $orig[0]['item_nocomment'] ); + $arr['item_obscured'] = ((array_key_exists('item_obscured',$arr)) ? intval($arr['item_obscured']) : $orig[0]['item_obscured'] ); + $arr['item_verified'] = ((array_key_exists('item_verified',$arr)) ? intval($arr['item_verified']) : $orig[0]['item_verified'] ); + $arr['item_retained'] = ((array_key_exists('item_retained',$arr)) ? intval($arr['item_retained']) : $orig[0]['item_retained'] ); + $arr['item_rss'] = ((array_key_exists('item_rss',$arr)) ? intval($arr['item_rss']) : $orig[0]['item_rss'] ); + $arr['item_deleted'] = ((array_key_exists('item_deleted',$arr)) ? intval($arr['item_deleted']) : $orig[0]['item_deleted'] ); + $arr['item_type'] = ((array_key_exists('item_type',$arr)) ? intval($arr['item_type']) : $orig[0]['item_type'] ); + $arr['item_hidden'] = ((array_key_exists('item_hidden',$arr)) ? intval($arr['item_hidden']) : $orig[0]['item_hidden'] ); + $arr['item_unpublished'] = ((array_key_exists('item_unpublished',$arr)) ? intval($arr['item_unpublished']) : $orig[0]['item_unpublished'] ); + $arr['item_delayed'] = ((array_key_exists('item_delayed',$arr)) ? intval($arr['item_delayed']) : $orig[0]['item_delayed'] ); + $arr['item_pending_remove'] = ((array_key_exists('item_pending_remove',$arr)) ? intval($arr['item_pending_remove']) : $orig[0]['item_pending_remove'] ); + $arr['item_blocked'] = ((array_key_exists('item_blocked',$arr)) ? intval($arr['item_blocked']) : $orig[0]['item_blocked'] ); + - $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'] ); $arr['sig'] = ((x($arr,'sig')) ? $arr['sig'] : ''); $arr['layout_mid'] = ((array_key_exists('layout_mid',$arr)) ? dbesc($arr['layout_mid']) : $orig[0]['layout_mid'] ); @@ -2818,11 +2819,10 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id, $x = array('signer' => $diaspora_handle, 'body' => $signed_body, 'signed_text' => $signed_text, 'signature' => base64_encode($authorsig)); - $key = get_config('system','pubkey'); - $y = crypto_encapsulate(json_encode($x),$key); + $y = json_encode($x); $r = q("update item set diaspora_meta = '%s' where id = %d", - dbesc(json_encode($y)), + dbesc($y), intval($post_id) ); @@ -2837,6 +2837,8 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id, function send_status_notifications($post_id,$item) { $notify = false; + $unfollowed = false; + $parent = 0; $r = q("select channel_hash from channel where channel_id = %d limit 1", @@ -2864,6 +2866,14 @@ function send_status_notifications($post_id,$item) { foreach($x as $xx) { if($xx['author_xchan'] === $r[0]['channel_hash']) { $notify = true; + + // check for an unfollow thread activity - we should probably decode the obj and check the id + // but it will be extremely rare for this to be wrong. + + if(($xx['verb'] === ACTIVITY_UNFOLLOW) + && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO) + && ($xx['parent'] != $xx['id'])) + $unfollowed = true; } if($xx['id'] == $xx['parent']) { $parent = $xx['parent']; @@ -2871,6 +2881,9 @@ function send_status_notifications($post_id,$item) { } } + if($unfollowed) + return; + $link = get_app()->get_baseurl() . '/display/' . $item['mid']; $y = q("select id from notify where link = '%s' and uid = %d limit 1", @@ -2947,8 +2960,8 @@ function tag_deliver($uid, $item_id) { $item = $i[0]; - if(($item['source_xchan']) && ($item['item_flags'] & ITEM_UPLINK) - && ($item['item_flags'] & ITEM_THREAD_TOP) && ($item['edited'] != $item['created'])) { + if(($item['source_xchan']) && intval($item['item_uplink']) + && intval($item['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 // Just start the second delivery chain to deliver the updated post proc_run('php','include/notifier.php','tgroup',$item['id']); @@ -2970,7 +2983,7 @@ function tag_deliver($uid, $item_id) { if($obj['id'] !== $u[0]['channel_hash']) $poke_notify = false; } - if($item['item_restrict'] & ITEM_DELETED) + if(intval($item['item_deleted'])) $poke_notify = false; $verb = urldecode(substr($item['verb'],strpos($item['verb'],'#')+1)); @@ -3047,13 +3060,13 @@ function tag_deliver($uid, $item_id) { // This might be a followup (e.g. comment) by the original post author to a tagged forum // If so setup a second delivery chain - if( ! ($item['item_flags'] & ITEM_THREAD_TOP)) { + if( ! intval($item['item_thread_top'])) { $x = q("select * from item where id = parent and parent = %d and uid = %d limit 1", intval($item['parent']), intval($uid) ); - if(($x) && ($x[0]['item_flags'] & ITEM_UPLINK)) { + if(($x) && intval($x[0]['item_uplink'])) { start_delivery_chain($u[0],$item,$item_id,$x[0]); } } @@ -3081,9 +3094,8 @@ function tag_deliver($uid, $item_id) { if($mention) { logger('tag_deliver: mention found for ' . $u[0]['channel_name']); - - $r = q("update item set item_flags = ( item_flags | %d ) where id = %d", - intval(ITEM_MENTIONSME), + + $r = q("update item set item_mentionsme = 1 where id = %d", intval($item_id) ); @@ -3093,7 +3105,7 @@ function tag_deliver($uid, $item_id) { $body = ''; - if($item['item_flags'] & ITEM_OBSCURED) { + if(intval($item['item_obscured'])) { $key = get_config('system','prvkey'); if($item['body']) $body = crypto_unencapsulate(json_decode_plus($item['body']),$key); @@ -3177,10 +3189,8 @@ function tag_deliver($uid, $item_id) { // prevent delivery looping - only proceed // if the message originated elsewhere and is a top-level post - if(($item['item_flags'] & ITEM_WALL) - || ($item['item_flags'] & ITEM_ORIGIN) - || (!($item['item_flags'] & ITEM_THREAD_TOP)) - || ($item['id'] != $item['parent'])) { + + if(intval($item['item_wall']) || intval($item['item_origin']) || (! intval($item['item_thread_top'])) || ($item['id'] != $item['parent'])) { logger('tag_deliver: item was local or a comment. rejected.'); return; } @@ -3205,10 +3215,9 @@ function tgroup_check($uid,$item) { // or is a followup and we have already accepted the top level post as an uplink if($item['mid'] != $item['parent_mid']) { - $r = q("select id from item where mid = '%s' and uid = %d and ( item_flags & %d )>0 limit 1", + $r = q("select id from item where mid = '%s' and uid = %d and item_uplink = 1 limit 1", dbesc($item['parent_mid']), - intval($uid), - intval(ITEM_UPLINK) + intval($uid) ); if($r) return true; @@ -3254,7 +3263,7 @@ function tgroup_check($uid,$item) { $body = $item['body']; - if(array_key_exists('item_flags',$item) && ($item['item_flags'] & ITEM_OBSCURED) && $body) { + if(array_key_exists('item_obscured',$item) && intval($item['item_obscured']) && $body) { $key = get_config('system','prvkey'); $body = crypto_unencapsulate(json_decode($body,true),$key); } @@ -3317,20 +3326,14 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { if((! $private) && $new_public_policy) $private = 1; - $flag_bits = $item['item_flags'] | ITEM_WALL; - - // The message didn't necessarily originate on this site, (we'll honour it if it did), - // but the parent post of this thread will be reset as a local post, as it is the top of - // this delivery chain and is coming from this site, regardless of where the original - // originated. - - if(! $parent) - $flag_bits = $flag_bits | ITEM_ORIGIN; - // unset the nocomment bit if it's there. + $item_wall = 1; + $item_origin = 1; + $item_uplink = 0; + $item_nocomment = 0; + $item_obscured = 0; - if($flag_bits & ITEM_NOCOMMENT) - $flag_bits = $flag_bits ^ ITEM_NOCOMMENT; + $flag_bits = $item['item_flags']; // maintain the original source, which will be the original item owner and was stored in source_xchan // when we created the delivery fork @@ -3342,7 +3345,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { ); } else { - $flag_bits = $flag_bits | ITEM_UPLINK; + $item_uplink = 1; $r = q("update item set source_xchan = owner_xchan where id = %d", intval($item_id) ); @@ -3351,29 +3354,11 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { $title = $item['title']; $body = $item['body']; - if($private) { - if(!($flag_bits & ITEM_OBSCURED)) { - $key = get_config('system','pubkey'); - $flag_bits = $flag_bits|ITEM_OBSCURED; - if($title) - $title = json_encode(crypto_encapsulate($title,$key)); - if($body) - $body = json_encode(crypto_encapsulate($body,$key)); - } - } - else { - if($flag_bits & ITEM_OBSCURED) { - $key = get_config('system','prvkey'); - $flag_bits = $flag_bits ^ ITEM_OBSCURED; - if($title) - $title = crypto_unencapsulate(json_decode($title,true),$key); - if($body) - $body = crypto_unencapsulate(json_decode($body,true),$key); - } - } - - $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", + $r = q("update item set item_uplink = %d, item_nocomment = %d, item_obscured = %d, 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', item_wall = %d, item_origin = %d where id = %d", + intval($item_uplink), + intval($item_nocomment), + intval($item_obscured), intval($flag_bits), dbesc($channel['channel_hash']), dbesc($channel['channel_allow_cid']), @@ -3385,6 +3370,8 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { dbesc(map_scope($channel['channel_w_comment'])), dbesc($title), dbesc($body), + intval($item_wall), + intval($item_origin), intval($item_id) ); @@ -3413,7 +3400,7 @@ function check_item_source($uid, $item) { if(! $r) return false; - $x = q("select abook_their_perms, abook_flags from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + $x = q("select abook_their_perms, abook_feed from abook where abook_channel = %d and abook_xchan = '%s' limit 1", intval($uid), dbesc($item['owner_xchan']) ); @@ -3424,7 +3411,7 @@ function check_item_source($uid, $item) { if(! ($x[0]['abook_their_perms'] & PERMS_A_REPUBLISH)) return false; - if($item['item_private'] && (! ($x[0]['abook_flags'] & ABOOK_FLAG_FEED))) + if($item['item_private'] && (! intval($x[0]['abook_feed']))) return false; if($r[0]['src_channel_xchan'] === $item['owner_xchan']) @@ -3481,6 +3468,7 @@ function post_is_importable($item,$abook) { $text = prepare_text($item['body'],$item['mimetype']); $text = html2plain($text); + $lang = null; if((strpos($abook['abook_incl'],'lang=') !== false) || (strpos($abook['abook_excl'],'lang=') !== false)) { @@ -3495,6 +3483,8 @@ function post_is_importable($item,$abook) { if($exclude) { foreach($exclude as $word) { $word = trim($word); + if(! $word) + continue; if(substr($word,0,1) === '#' && $tags) { foreach($tags as $t) if(($t['type'] == TERM_HASHTAG) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) @@ -3514,6 +3504,8 @@ function post_is_importable($item,$abook) { if($include) { foreach($include as $word) { $word = trim($word); + if(! $word) + continue; if(substr($word,0,1) === '#' && $tags) { foreach($tags as $t) if(($t['type'] == TERM_HASHTAG) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*'))) @@ -3542,8 +3534,10 @@ function mail_store($arr) { return 0; } - if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false)) - $arr['body'] = escape_tags($arr['body']); + if(! $arr['mail_obscured']) { + if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false)) + $arr['body'] = escape_tags($arr['body']); + } if(array_key_exists('attach',$arr) && is_array($arr['attach'])) $arr['attach'] = json_encode($arr['attach']); @@ -3554,9 +3548,10 @@ function mail_store($arr) { $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()); $arr['expires'] = ((x($arr,'expires') !== false) ? datetime_convert('UTC','UTC',$arr['expires']) : NULL_DATE); - $arr['title'] = ((x($arr,'title')) ? notags(trim($arr['title'])) : ''); + $arr['title'] = ((x($arr,'title')) ? trim($arr['title']) : ''); $arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : ''); $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); + $arr['conv_guid'] = ((x($arr,'conv_guid')) ? trim($arr['conv_guid']) : ''); $arr['mail_flags'] = ((x($arr,'mail_flags')) ? intval($arr['mail_flags']) : 0 ); @@ -3569,11 +3564,17 @@ function mail_store($arr) { dbesc($arr['mid']), intval($arr['channel_id']) ); + if($r) { logger('mail_store: duplicate item ignored. ' . print_r($arr,true)); return 0; } + if(! $r && $arr['mail_recalled'] == 1) { + logger('mail_store: recalled item not found. ' . print_r($arr,true)); + return 0; + } + call_hooks('post_mail',$arr); if(x($arr,'cancel')) { @@ -3709,7 +3710,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { if($r) { $item = $r[0]; - if(! ($item['item_restrict'] & ITEM_DELETED)) { + if(! intval($item['item_deleted'])) { logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . base64url_decode($item['mid']), LOGGER_DEBUG); drop_item($item['id'],false); } @@ -4207,22 +4208,23 @@ function item_expire($uid,$days) { $expire_network_only = 1; + $sql_extra = ((intval($expire_network_only)) ? " AND item_wall = 0 " : ""); + $expire_limit = get_config('system','expire_limit'); if(! intval($expire_limit)) $expire_limit = 5000; - $sql_extra = ((intval($expire_network_only)) ? " AND (item_flags & " . intval(ITEM_WALL) . ") = 0 " : ""); + $item_normal = item_normal(); $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `created` < %s - INTERVAL %s AND `id` = `parent` $sql_extra - AND ( item_flags & %d ) = 0 - AND ( item_restrict = 0 ) LIMIT $expire_limit ", + AND item_retained = 0 + $item_normal LIMIT $expire_limit ", intval($uid), - db_utcnow(), db_quoteinterval(intval($days).' DAY'), - intval(ITEM_RETAINED) + db_utcnow(), db_quoteinterval(intval($days).' DAY') ); if(! $r) @@ -4246,7 +4248,7 @@ function item_expire($uid,$days) { retain_item($item['id']); continue; } - if($item['item_flags'] & ITEM_STARRED) { + if(intval($item['item_starred'])) { retain_item($item['id']); continue; } @@ -4258,8 +4260,7 @@ function item_expire($uid,$days) { } function retain_item($id) { - $r = q("update item set item_flags = (item_flags | %d ) where id = %d", - intval(ITEM_RETAINED), + $r = q("update item set item_retained = 1 where id = %d", intval($id) ); } @@ -4304,7 +4305,7 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal intval($id) ); - if((! $r) || (($r[0]['item_restrict'] & ITEM_DELETED) && ($stage === DROPITEM_NORMAL))) { + if((! $r) || (intval($r[0]['item_deleted']) && ($stage === DROPITEM_NORMAL))) { if(! $interactive) return 0; notice( t('Item not found.') . EOL); @@ -4340,10 +4341,16 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal // 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", - intval(($linked_item && ! $force) ? ITEM_HIDDEN : ITEM_DELETED), - intval($item['id']) - ); + if(($linked_item) && (! $force)) { + $r = q("UPDATE item SET item_hidden = 1 WHERE id = %d", + intval($item['id']) + ); + } + else { + $r = q("UPDATE item SET item_deleted = 1 WHERE id = %d", + intval($item['id']) + ); + } $arr = array('item' => $item, 'interactive' => $interactive, 'stage' => $stage); call_hooks('drop_item', $arr ); @@ -4372,7 +4379,7 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal // We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only // set if we know we're going to send delete notifications out to others. - if((($item['item_flags'] & ITEM_WALL) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1)) + if((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1)) proc_run('php','include/notifier.php','drop',$notify_id); goaway($a->get_baseurl() . '/' . $_SESSION['return_url']); @@ -4404,9 +4411,8 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) { switch($stage) { case DROPITEM_PHASE2: - $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '', + $r = q("UPDATE item SET item_pending_remove = 1, body = '', title = '', changed = '%s', edited = '%s' WHERE id = %d", - intval(ITEM_PENDING_REMOVE), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item['id']) @@ -4414,30 +4420,37 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) { break; case DROPITEM_PHASE1: - $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), - changed = '%s', edited = '%s' WHERE id = %d", - intval(($linked_item && ! $force) ? ITEM_HIDDEN : ITEM_DELETED), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($item['id']) - ); + if($linked_item && ! $force) { + $r = q("UPDATE item SET item_hidden = 1, + changed = '%s', edited = '%s' WHERE id = %d", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($item['id']) + ); + } + else { + $r = q("UPDATE item set item_deleted = 1, changed = '%s', edited = '%s' where id = %d", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($item['id']) + ); + } + break; case DROPITEM_NORMAL: default: if($linked_item && ! $force) { - $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), + $r = q("UPDATE item SET item_hidden = 1, changed = '%s', edited = '%s' WHERE id = %d", - intval(ITEM_HIDDEN), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item['id']) ); } else { - $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '', + $r = q("UPDATE item SET item_deleted = 1, body = '', title = '', changed = '%s', edited = '%s' WHERE id = %d", - intval(ITEM_DELETED), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item['id']) @@ -4453,6 +4466,18 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) { intval($item['uid']) ); + // remove delivery reports + + $c = q("select channel_hash from channel where channel_id = %d limit 1", + intval($item['uid']) + ); + if($c) { + q("delete from dreport where dreport_xchan = '%s' and dreport_mid = '%s'", + dbesc($c[0]['channel_hash']), + dbesc($item['mid']) + ); + } + // 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). @@ -4482,12 +4507,12 @@ function delete_item_lowlevel($item, $stage = DROPITEM_NORMAL, $force = false) { function first_post_date($uid,$wall = false) { - $wall_sql = (($wall) ? sprintf(" and (item_flags & %d)>0 ", ITEM_WALL) : "" ); + $wall_sql = (($wall) ? " and item_wall = 1 " : "" ); + $item_normal = item_normal(); $r = q("select id, created from item - where item_restrict = %d and uid = %d and id = parent $wall_sql + where uid = %d and id = parent $item_normal $wall_sql order by created asc limit 1", - intval(ITEM_VISIBLE), intval($uid) ); @@ -4688,23 +4713,23 @@ function zot_feed($uid,$observer_hash,$arr) { $groupby = 'GROUP BY parent'; } + $item_normal = item_normal(); + if(is_sys_channel($uid)) { $r = q("SELECT parent, created, postopts from item WHERE uid != %d - AND item_private = 0 AND item_restrict = 0 AND uid in (" . stream_perms_api_uids(PERMS_PUBLIC,10,1) . ") - AND (item_flags & %d) > 0 - $sql_extra $groupby ORDER BY created ASC $limit", - intval($uid), - intval(ITEM_WALL) + $item_normal + AND item_wall = 1 + and item_private = 0 $sql_extra $groupby ORDER BY created ASC $limit", + intval($uid) ); } else { $r = q("SELECT parent, created, postopts from item - WHERE uid = %d AND item_restrict = 0 - AND (item_flags & %d) > 0 + WHERE uid = %d $item_normal + AND item_wall = 1 $sql_extra $groupby ORDER BY created ASC $limit", - intval($uid), - intval(ITEM_WALL) + intval($uid) ); } @@ -4717,10 +4742,10 @@ function zot_feed($uid,$observer_hash,$arr) { $parents_str = ids_to_querystr($r,'parent'); $sys_query = ((is_sys_channel($uid)) ? $sql_extra : ''); + $item_normal = item_normal(); $items = q("SELECT `item`.*, `item`.`id` AS `item_id` FROM `item` - WHERE `item`.`item_restrict` = 0 - AND `item`.`parent` IN ( %s ) $sys_query ", + WHERE `item`.`parent` IN ( %s ) $item_normal $sys_query ", dbesc($parents_str) ); } @@ -4758,6 +4783,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $def_acl = ''; $item_uids = ' true '; + $item_normal = item_normal(); + if ($arr['uid']) $uid= $arr['uid']; @@ -4768,13 +4795,19 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } if($arr['star']) - $sql_options .= " and (item_flags & " . intval(ITEM_STARRED) . ")>0 "; + $sql_options .= " and item_starred = 1 "; if($arr['wall']) - $sql_options .= " and (item_flags & " . intval(ITEM_WALL) . ")>0 "; + $sql_options .= " and item_wall = 1 "; - $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE (item_flags & " . intval(ITEM_THREAD_TOP) . ")>0 $sql_options ) "; + if($arr['item_id']) + $sql_options .= " and parent = " . intval($arr['item_id']) . " "; + if($arr['mid']) + $sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' "; + + $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) "; + if($arr['since_id']) $sql_extra .= " and item.id > " . $since_id . " "; @@ -4804,19 +4837,19 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C return $result; } - $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 ) "; + $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 $item_normal ) "; $x = group_rec_byhash($uid,$r[0]['hash']); $result['headline'] = sprintf( t('Collection: %s'),$x['name']); } elseif($arr['cid'] && $uid) { - $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) . ")>0 limit 1", + $r = q("SELECT abook.*, xchan.* from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_channel = %d and abook_blocked = 0 limit 1", intval($arr['cid']), intval(local_channel()) ); if ($r) { - $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 ) "; + $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']) . "' ) $item_normal ) "; $result['headline'] = sprintf( t('Connection: %s'),$r[0]['xchan_name']); } else { $result['message'] = t('Connection not found.'); @@ -4837,24 +4870,24 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } 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); - } + 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 ($arr['conv'] && $channel) { - $sql_extra .= sprintf(" AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or ( item_flags & %d )>0)) ", - dbesc(protect_sprintf($uidhash)), - intval(ITEM_MENTIONSME) - ); - } + if(strlen($arr['file'])) { + $sql_extra .= term_query('item',$arr['files'],TERM_FILE); + } + + if($arr['conv'] && $channel) { + $sql_extra .= sprintf(" AND parent IN (SELECT distinct parent from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ", + dbesc(protect_sprintf($uidhash)) + ); + } if (($client_mode & CLIENT_MODE_UPDATE) && (! ($client_mode & CLIENT_MODE_LOAD))) { // only setup pagination on initial page view @@ -4889,19 +4922,23 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C } } - $simple_update = (($client_mode & CLIENT_MODE_UPDATE) ? " and ( item.item_unseen = 1 ) " : ''); - if ($client_mode & CLIENT_MODE_LOAD) - $simple_update = ''; + $simple_update = (($client_mode & CLIENT_MODE_UPDATE) ? " and item.item_unseen = 1 " : ''); + if($client_mode & CLIENT_MODE_LOAD) + $simple_update = ''; //$start = dba_timer(); require_once('include/security.php'); $sql_extra .= item_permissions_sql($channel['channel_id'],$observer_hash); - if ($arr['pages']) - $item_restrict = " AND (item_restrict & " . ITEM_WEBPAGE . ") "; + + if($arr['pages']) + $item_restrict = " AND item_type = " . ITEM_TYPE_WEBPAGE . " "; else - $item_restrict = " AND item_restrict = 0 "; + $item_restrict = " AND item_type = 0 "; + + if($arr['item_type'] === '*') + $item_restrict = ''; if ($arr['nouveau'] && ($client_mode & CLIENT_MODE_LOAD) && $channel) { // "New Item View" - show all items unthreaded in reverse created date order @@ -4935,10 +4972,9 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C left join abook on item.author_xchan = abook.abook_xchan WHERE $item_uids $item_restrict AND item.parent = item.id - and ((abook.abook_flags & %d) = 0 or abook.abook_flags is null) + and (abook.abook_blocked = 0 or abook.abook_flags is null) $sql_extra3 $sql_extra $sql_nets - ORDER BY item.$ordering DESC $pager_sql ", - intval(ABOOK_FLAG_BLOCKED) + ORDER BY item.$ordering DESC $pager_sql " ); } @@ -4947,9 +4983,8 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C $r = q("SELECT item.parent AS item_id FROM item left join abook on item.author_xchan = abook.abook_xchan WHERE $item_uids $item_restrict $simple_update - and ((abook.abook_flags & %d) = 0 or abook.abook_flags is null) - $sql_extra3 $sql_extra $sql_nets ", - intval(ABOOK_FLAG_BLOCKED) + and (abook.abook_blocked = 0 or abook.abook_flags is null) + $sql_extra3 $sql_extra $sql_nets " ); } @@ -5005,12 +5040,14 @@ function update_remote_id($channel,$post_id,$webpage,$pagetitle,$namespace,$remo if(! $post_id) return; - if($webpage & ITEM_WEBPAGE) + if($webpage == ITEM_TYPE_WEBPAGE) $page_type = 'WEBPAGE'; - elseif($webpage & ITEM_BUILDBLOCK) + elseif($webpage == ITEM_TYPE_BLOCK) $page_type = 'BUILDBLOCK'; - elseif($webpage & ITEM_PDL) + elseif($webpage == ITEM_TYPE_PDL) $page_type = 'PDL'; + elseif($webpage == ITEM_TYPE_DOC) + $page_type = 'docfile'; elseif($namespace && $remote_id) { $page_type = $namespace; $pagetitle = $remote_id; |