diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 2 | ||||
-rw-r--r-- | include/ConversationObject.php | 4 | ||||
-rw-r--r-- | include/ItemObject.php | 18 | ||||
-rw-r--r-- | include/RedDAV/RedBrowser.php | 9 | ||||
-rw-r--r-- | include/account.php | 26 | ||||
-rw-r--r-- | include/bbcode.php | 6 | ||||
-rw-r--r-- | include/conversation.php | 66 | ||||
-rw-r--r-- | include/crypto.php | 6 | ||||
-rw-r--r-- | include/dir_fns.php | 11 | ||||
-rw-r--r-- | include/features.php | 79 | ||||
-rw-r--r-- | include/identity.php | 16 | ||||
-rwxr-xr-x | include/items.php | 126 | ||||
-rw-r--r-- | include/nav.php | 10 | ||||
-rw-r--r-- | include/network.php | 4 | ||||
-rw-r--r-- | include/notifier.php | 1 | ||||
-rw-r--r-- | include/text.php | 76 | ||||
-rw-r--r-- | include/zot.php | 14 |
17 files changed, 315 insertions, 159 deletions
diff --git a/include/Contact.php b/include/Contact.php index 233798181..4f7a2a19f 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -519,6 +519,8 @@ function contact_remove($channel_id, $abook_id) { if((! $channel_id) || (! $abook_id)) return false; + logger('removing contact ' . $abook_id . ' for channel ' . $channel_id,LOGGER_DEBUG); + $archive = get_pconfig($channel_id, 'system','archive_removed_contacts'); if($archive) { q("update abook set abook_flags = ( abook_flags | %d ) where abook_id = %d and abook_channel = %d", diff --git a/include/ConversationObject.php b/include/ConversationObject.php index a02ba102f..7dc4c8c19 100644 --- a/include/ConversationObject.php +++ b/include/ConversationObject.php @@ -197,7 +197,7 @@ class Conversation extends BaseObject { * _ The data requested on success * _ false on failure */ - public function get_template_data($alike, $dlike) { + public function get_template_data($conv_responses) { $result = array(); foreach($this->threads as $item) { @@ -206,7 +206,7 @@ class Conversation extends BaseObject { $item_data = $this->prepared_item; } else { - $item_data = $item->get_template_data($alike, $dlike); + $item_data = $item->get_template_data($conv_responses); } if(!$item_data) { logger('[ERROR] Conversation::get_template_data : Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG); diff --git a/include/ItemObject.php b/include/ItemObject.php index ec8116297..82a321732 100644 --- a/include/ItemObject.php +++ b/include/ItemObject.php @@ -63,7 +63,7 @@ class Item extends BaseObject { * _ false on failure */ - public function get_template_data($alike, $dlike, $thread_level=1) { + public function get_template_data($conv_responses, $thread_level=1) { $result = array(); @@ -135,8 +135,8 @@ class Item extends BaseObject { $location = format_location($item); - $like_count = ((x($alike,$item['mid'])) ? $alike[$item['mid']] : ''); - $like_list = ((x($alike,$item['mid'])) ? $alike[$item['mid'] . '-l'] : ''); + $like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : ''); + $like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : ''); if (count($like_list) > MAX_LIKERS) { $like_list_part = array_slice($like_list, 0, MAX_LIKERS); array_push($like_list_part, '<a href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>'); @@ -146,8 +146,8 @@ class Item extends BaseObject { $like_button_label = tt('Like','Likes',$like_count,'noun'); if (feature_enabled($conv->get_profile_owner(),'dislike')) { - $dislike_count = ((x($dlike,$item['mid'])) ? $dlike[$item['mid']] : ''); - $dislike_list = ((x($dlike,$item['mid'])) ? $dlike[$item['mid'] . '-l'] : ''); + $dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : ''); + $dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : ''); $dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun'); if (count($dislike_list) > MAX_LIKERS) { $dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS); @@ -157,9 +157,9 @@ class Item extends BaseObject { } } - $showlike = ((x($alike,$item['mid'])) ? format_like($alike[$item['mid']],$alike[$item['mid'] . '-l'],'like',$item['mid']) : ''); - $showdislike = ((x($dlike,$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike')) - ? format_like($dlike[$item['mid']],$dlike[$item['mid'] . '-l'],'dislike',$item['mid']) : ''); + $showlike = ((x($conv_responses['like'],$item['mid'])) ? format_like($conv_responses['like'][$item['mid']],$conv_responses['like'][$item['mid'] . '-l'],'like',$item['mid']) : ''); + $showdislike = ((x($conv_responses['dislike'],$item['mid']) && feature_enabled($conv->get_profile_owner(),'dislike')) + ? format_like($conv_responses['dislike'][$item['mid']],$conv_responses['dislike'][$item['mid'] . '-l'],'dislike',$item['mid']) : ''); /* * We should avoid doing this all the time, but it depends on the conversation mode @@ -336,7 +336,7 @@ class Item extends BaseObject { if(($this->get_display_mode() === 'normal') && ($nb_children > 0)) { foreach($children as $child) { - $result['children'][] = $child->get_template_data($alike, $dlike, $thread_level + 1); + $result['children'][] = $child->get_template_data($conv_responses, $thread_level + 1); } // Collapse if(($nb_children > 2) || ($thread_level > 1)) { diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php index 709f6339b..9ea2b9808 100644 --- a/include/RedDAV/RedBrowser.php +++ b/include/RedDAV/RedBrowser.php @@ -267,6 +267,15 @@ class RedBrowser extends DAV\Browser\Plugin { get_app()->page['content'] = $html; load_pdl(get_app()); + + $theme_info_file = "view/theme/" . current_theme() . "/php/theme.php"; + if (file_exists($theme_info_file)){ + require_once($theme_info_file); + if (function_exists(str_replace('-', '_', current_theme()) . '_init')) { + $func = str_replace('-', '_', current_theme()) . '_init'; + $func(get_app()); + } + } construct_page(get_app()); } diff --git a/include/account.php b/include/account.php index 8df44acba..88036e2ef 100644 --- a/include/account.php +++ b/include/account.php @@ -590,6 +590,32 @@ function service_class_allows($uid,$property,$usage = false) { } } +// like service_class_allows but queries by account rather than channel +function account_service_class_allows($aid,$property,$usage = false) { + $a = get_app(); + $r = q("select account_service_class as service_class from account where account_id = %d limit 1", + intval($aid) + ); + if($r !== false and count($r)) { + $service_class = $r[0]['service_class']; + } + + if(! x($service_class)) + return true; // everything is allowed + + $arr = get_config('service_class',$service_class); + if(! is_array($arr) || (! count($arr))) + return true; + + if($usage === false) + return ((x($arr[$property])) ? (bool) $arr[$property] : true); + else { + if(! array_key_exists($property,$arr)) + return true; + return (((intval($usage)) < intval($arr[$property])) ? true : false); + } +} + function service_class_fetch($uid,$property) { $a = get_app(); diff --git a/include/bbcode.php b/include/bbcode.php index ab56bda61..33017c011 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -437,7 +437,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) { // replace [observer.baseurl] if ($observer) { - $s1 = '<span class="bb_observer">'; + $s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">'; $s2 = '</span>'; $obsBaseURL = $observer['xchan_connurl']; $obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL); @@ -575,6 +575,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) { if (strpos($Text,'[h6]') !== false) { $Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text); } + // Check for table of content + if (strpos($Text,'[toc]') !== false) { + $Text = preg_replace("/\[toc\]/ism",'<ul id="toc"></ul>',$Text); + } // Check for centered text if (strpos($Text,'[/center]') !== false) { $Text = preg_replace("(\[center\](.*?)\[\/center\])ism","<div style=\"text-align:center;\">$1</div>",$Text); diff --git a/include/conversation.php b/include/conversation.php index a2fb3d162..0d59ff92e 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -264,6 +264,7 @@ function localize_item(&$item){ } + /* // FIXME store parent item as object or target // (and update to json storage) @@ -398,10 +399,15 @@ function count_descendants($item) { function visible_activity($item) { - // likes can apply to other things besides posts. Check if they are post children, in which case we handle them specially + // likes (etc.) can apply to other things besides posts. Check if they are post children, + // in which case we handle them specially - if((activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)) && ($item['mid'] != $item['parent_mid'])) - return false; + $hidden_activities = array(ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN); + foreach($hidden_activities as $act) { + if((activity_match($item['verb'],$act)) && ($item['mid'] != $item['parent_mid'])) { + return false; + } + } return true; } @@ -546,8 +552,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $items = $cb['items']; - $alike = array(); - $dlike = array(); + $conv_responses = array(array('like'),array('dislike'),array('agree'),array('disagree'),array('abstain')); // array with html for each thread (parent+comments) $threads = array(); @@ -778,10 +783,14 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ } } - like_puller($a, $item, $alike, 'like'); + like_puller($a, $item, $conv_responses, 'like'); if(feature_enabled($profile_owner, 'dislike')) - like_puller($a, $item, $dlike, 'dislike'); + like_puller($a, $item, $conv_responses, 'dislike'); + + like_puller($a, $item, $conv_responses, 'agree'); + like_puller($a, $item, $conv_responses, 'disagree'); + like_puller($a, $item, $conv_responses, 'abstain'); if(! visible_activity($item)) { continue; @@ -800,7 +809,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ } } - $threads = $conv->get_template_data($alike, $dlike); + $threads = $conv->get_template_data($conv_responses); if(!$threads) { logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); $threads = array(); @@ -971,7 +980,32 @@ function item_photo_menu($item){ function like_puller($a, $item, &$arr, $mode) { $url = ''; - $verb = (($mode === 'like') ? ACTIVITY_LIKE : ACTIVITY_DISLIKE); + + switch($mode) { + case 'like': + case 'unlike': + $verb = ACTIVITY_LIKE; + break; + case 'dislike': + case 'undislike': + $verb = ACTIVITY_DISLIKE; + break; + case 'agree': + case 'unagree': + $verb = ACTIVITY_AGREE; + break; + case 'disagree': + case 'undisagree': + $verb = ACTIVITY_DISAGREE; + break; + case 'abstain': + case 'unabstain': + $verb = ACTIVITY_ABSTAIN; + break; + default: + return; + break; + } if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) { @@ -981,20 +1015,20 @@ function like_puller($a, $item, &$arr, $mode) { if(! $item['thr_parent']) $item['thr_parent'] = $item['parent_mid']; - if(! ((isset($arr[$item['thr_parent'] . '-l'])) && (is_array($arr[$item['thr_parent'] . '-l'])))) - $arr[$item['thr_parent'] . '-l'] = array(); + if(! ((isset($arr[$mode][$item['thr_parent'] . '-l'])) && (is_array($arr[$mode][$item['thr_parent'] . '-l'])))) + $arr[$mode][$item['thr_parent'] . '-l'] = array(); - if(! isset($arr[$item['thr_parent']])) - $arr[$item['thr_parent']] = 1; + if(! isset($arr[$mode][$item['thr_parent']])) + $arr[$mode][$item['thr_parent']] = 1; else - $arr[$item['thr_parent']] ++; + $arr[$mode][$item['thr_parent']] ++; $name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown')); if($url) - $arr[$item['thr_parent'] . '-l'][] = '<a href="'. $url . '">' . $name . '</a>'; + $arr[$mode][$item['thr_parent'] . '-l'][] = '<a href="'. $url . '">' . $name . '</a>'; else - $arr[$item['thr_parent'] . '-l'][] = '<a href="#" class="disabled">' . $name . '</a>'; + $arr[$mode][$item['thr_parent'] . '-l'][] = '<a href="#" class="disabled">' . $name . '</a>'; } return; } diff --git a/include/crypto.php b/include/crypto.php index 07655e24f..ab083cfaa 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -39,6 +39,9 @@ function pkcs5_unpad($text) } function AES256CBC_encrypt($data,$key,$iv) { + if(get_config('system','openssl_encrypt')) { + return openssl_encrypt($data,'aes-256-cbc',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0")); + } return mcrypt_encrypt( MCRYPT_RIJNDAEL_128, str_pad($key,32,"\0"), @@ -48,6 +51,9 @@ function AES256CBC_encrypt($data,$key,$iv) { } function AES256CBC_decrypt($data,$key,$iv) { + if(get_config('system','openssl_encrypt')) { + return openssl_decrypt($data,'aes-256-cbc',str_pad($key,32,"\0"),OPENSSL_RAW_DATA,str_pad($iv,16,"\0")); + } return pkcs5_unpad(mcrypt_decrypt( MCRYPT_RIJNDAEL_128, str_pad($key,32,"\0"), diff --git a/include/dir_fns.php b/include/dir_fns.php index af6f78c01..371ee0fbc 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -55,13 +55,18 @@ function dir_sort_links() { // Probably there's an easier way to do this $current_order = (($_REQUEST['order']) ? $_REQUEST['order'] : 'normal'); - $url = 'directory?'; - $tmp = $_REQUEST; + $url = 'directory?f='; + + $tmp = array_merge($_GET,$_POST); unset($tmp['order']); + unset($tmp['q']); + unset($tmp['f']); $sorturl = $url . http_build_query($tmp); - $tmp = $_REQUEST; + $tmp = array_merge($_GET,$_POST); unset($tmp['pubforums']); + unset($tmp['q']); + unset($tmp['f']); $forumsurl = $url . http_build_query($tmp); $o = replace_macros(get_markup_template('dir_sort_links.tpl'), array( diff --git a/include/features.php b/include/features.php index 7009b1d6b..1a4b2654f 100644 --- a/include/features.php +++ b/include/features.php @@ -7,13 +7,28 @@ function feature_enabled($uid,$feature) { $x = get_pconfig($uid,'feature',$feature); - if($x === false) + if($x === false) { $x = get_config('feature',$feature); + if($x === false) + $x = get_feature_default($feature); + } $arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x); call_hooks('feature_enabled',$arr); return($arr['enabled']); } +function get_feature_default($feature) { + $f = get_features(); + foreach($f as $cat) { + foreach($cat as $feat) { + if(is_array($feat) && $feat[0] === $feature) + return $feat[3]; + } + } + return false; +} + + function get_features() { $arr = array( @@ -22,58 +37,52 @@ function get_features() { 'general' => array( t('General Features'), // This is per post, and different from fixed expiration 'expire' which isn't working yet - array('content_expire', t('Content Expiration'), t('Remove posts/comments and/or private messages at a future time')), - array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles')), - array('advanced_profiles', t('Advanced Profiles'), t('Additional profile sections and selections')), - array('profile_export', t('Profile Import/Export'), t('Save and load profile details across sites/channels')), - array('webpages', t('Web Pages'), t('Provide managed web pages on your channel')), - array('private_notes', t('Private Notes'), t('Enables a tool to store notes and reminders')), -// prettyphoto has licensing issues and will no longer be provided in core - -// in any event this setting should probably be a theme option or plugin -// array('prettyphoto', t('Enhanced Photo Albums'), t('Enable photo album with enhanced features')), - array('nav_channel_select', t('Navigation Channel Select'), t('Change channels directly from within the navigation dropdown menu')), + array('content_expire', t('Content Expiration'), t('Remove posts/comments and/or private messages at a future time'), false), + array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false), + array('advanced_profiles', t('Advanced Profiles'), t('Additional profile sections and selections'),false), + array('profile_export', t('Profile Import/Export'), t('Save and load profile details across sites/channels'),false), + array('webpages', t('Web Pages'), t('Provide managed web pages on your channel'),false), + array('private_notes', t('Private Notes'), t('Enables a tool to store notes and reminders'),false), + array('nav_channel_select', t('Navigation Channel Select'), t('Change channels directly from within the navigation dropdown menu'),false), //FIXME - needs a description, but how the hell do we explain this to normals? - array('sendzid', t('Extended Identity Sharing'), t('Share your identity with all websites on the internet. When disabled, identity is only shared with sites in the matrix.')), - array('expert', t('Expert Mode'), t('Enable Expert Mode to provide advanced configuration options')), - array('premium_channel', t('Premium Channel'), t('Allows you to set restrictions and terms on those that connect with your channel')), + array('sendzid', t('Extended Identity Sharing'), t('Share your identity with all websites on the internet. When disabled, identity is only shared with sites in the matrix.'),false), + array('expert', t('Expert Mode'), t('Enable Expert Mode to provide advanced configuration options'),false), + array('premium_channel', t('Premium Channel'), t('Allows you to set restrictions and terms on those that connect with your channel'),false), ), // Post composition 'composition' => array( t('Post Composition Features'), -// array('richtext', t('Richtext Editor'), t('Enable richtext editor')), - array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts')), -// array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them')), - array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds')), - array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key')), - array('adult_photo_flagging', t('Flag Adult Photos'), t('Provide photo edit option to hide adult photos from default album view')), +// array('richtext', t('Richtext Editor'), t('Enable richtext editor'),false), + array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false), + array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds'),false), + array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key'),false), + array('adult_photo_flagging', t('Flag Adult Photos'), t('Provide photo edit option to hide adult photos from default album view'),false), ), // Network Tools 'net_module' => array( t('Network and Stream Filtering'), - array('archives', t('Search by Date'), t('Ability to select posts by date ranges')), - array('groups', t('Collections Filter'), t('Enable widget to display Network posts only from selected collections')), - array('savedsearch', t('Saved Searches'), t('Save search terms for re-use')), - array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on')), - array('new_tab', t('Network New Tab'), t('Enable tab to display all new Network activity')), - array('affinity', t('Affinity Tool'), t('Filter stream activity by depth of relationships')), - array('suggest', t('Suggest Channels'), t('Show channel suggestions')), + array('archives', t('Search by Date'), t('Ability to select posts by date ranges'),false), + array('groups', t('Collections Filter'), t('Enable widget to display Network posts only from selected collections'),false), + array('savedsearch', t('Saved Searches'), t('Save search terms for re-use'),false), + array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'),false), + array('new_tab', t('Network New Tab'), t('Enable tab to display all new Network activity'),false), + array('affinity', t('Affinity Tool'), t('Filter stream activity by depth of relationships'),false), + array('suggest', t('Suggest Channels'), t('Show channel suggestions'),false), ), // Item tools 'tools' => array( t('Post/Comment Tools'), -// array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once')), -// array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending')), - array('commtag', t('Tagging'), t('Ability to tag existing posts')), - array('categories', t('Post Categories'), t('Add categories to your posts')), - array('filing', t('Saved Folders'), t('Ability to file posts under folders')), - array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments')), - array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator')), - array('tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your channel page')), + array('commtag', t('Tagging'), t('Ability to tag existing posts'),false), + array('categories', t('Post Categories'), t('Add categories to your posts'),false), + array('filing', t('Saved Folders'), t('Ability to file posts under folders'),false), + array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'),false), + array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'),false), + array('tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your channel page'),false), ), ); diff --git a/include/identity.php b/include/identity.php index 17238ea99..d98f39cb7 100644 --- a/include/identity.php +++ b/include/identity.php @@ -34,7 +34,7 @@ function identity_check_service_class($account_id) { $ret['total_identities'] = intval($r[0]['total']); - if(! service_class_allows($account_id,'total_identities',$r[0]['total'])) { + if(! account_service_class_allows($account_id,'total_identities',$r[0]['total'])) { $result['message'] .= upgrade_message(); return $result; } @@ -1205,21 +1205,9 @@ function advanced_profile(&$a) { if($txt = prepare_text($a->profile['dislikes'])) $profile['dislikes'] = array( t('Dislikes:'), $txt); - if($txt = prepare_text($a->profile['contact'])) $profile['contact'] = array( t('Contact information and Social Networks:'), $txt); - // Support tags in the other channels field (probably want to restrict it to channels only?) - $txt = $a->profile['channels']; - $matches = get_tags($txt); - $access_tag = ''; - $str_tags = ''; - foreach($matches as $m) { - $success = handle_tag($a, $txt, $access_tag, $str_tags, $a->profile_uid, $m); // Use uid of the profile maker - } - - if($txt = prepare_text($txt)) { - $profile['channels'] = array( t('My other channels:'), $txt); - } + if($txt = prepare_text($a->profile['channels'])) $profile['channels'] = array( t('My other channels:'), $txt); if($txt = prepare_text($a->profile['music'])) $profile['music'] = array( t('Musical interests:'), $txt); diff --git a/include/items.php b/include/items.php index c488e1953..fb2f2586a 100755 --- a/include/items.php +++ b/include/items.php @@ -419,6 +419,9 @@ function post_activity_item($arr) { $arr['verb'] = ((x($arr,'verb')) ? $arr['verb'] : ACTIVITY_POST); $arr['obj_type'] = ((x($arr,'obj_type')) ? $arr['obj_type'] : ACTIVITY_OBJ_NOTE); + if($is_comment) + $arr['obj_type'] = ACTIVITY_OBJ_COMMENT; + $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']); @@ -834,8 +837,15 @@ function get_item_elements($x) { $arr['item_flags'] = 0; + if(array_key_exists('flags',$x) && in_array('consensus',$x['flags'])) + $arr['item_flags'] |= ITEM_CONSENSUS; + + + if(array_key_exists('flags',$x) && in_array('deleted',$x['flags'])) - $arr['item_restrict'] = ITEM_DELETED; + $arr['item_restrict'] = ITEM_DELETED; + if(array_key_exists('flags',$x) && in_array('hidden',$x['flags'])) + $arr['item_restrict'] = ITEM_HIDDEN; // 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 @@ -1306,10 +1316,14 @@ function encode_item_flags($item) { if($item['item_restrict'] & ITEM_DELETED) $ret[] = 'deleted'; + if($item['item_restrict'] & ITEM_HIDDEN) + $ret[] = 'hidden'; if($item['item_flags'] & ITEM_THREAD_TOP) $ret[] = 'thread_parent'; if($item['item_flags'] & ITEM_NSFW) $ret[] = 'nsfw'; + if($item['item_flags'] & ITEM_CONSENSUS) + $ret[] = 'consensus'; if($item['item_private']) $ret[] = 'private'; @@ -2015,8 +2029,8 @@ function item_store($arr,$allow_exec = false) { $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : ''); $arr['parent_mid'] = ((x($arr,'parent_mid')) ? notags(trim($arr['parent_mid'])) : ''); $arr['thr_parent'] = ((x($arr,'thr_parent')) ? notags(trim($arr['thr_parent'])) : $arr['parent_mid']); - $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : ''); - $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : ''); + $arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : ACTIVITY_POST); + $arr['obj_type'] = ((x($arr,'obj_type')) ? notags(trim($arr['obj_type'])) : ACTIVITY_OBJ_NOTE); $arr['object'] = ((x($arr,'object')) ? trim($arr['object']) : ''); $arr['tgt_type'] = ((x($arr,'tgt_type')) ? notags(trim($arr['tgt_type'])) : ''); $arr['target'] = ((x($arr,'target')) ? trim($arr['target']) : ''); @@ -2080,6 +2094,8 @@ function item_store($arr,$allow_exec = false) { return $ret; } + if($arr['obj_type'] == ACTIVITY_OBJ_NOTE) + $arr['obj_type'] = ACTIVITY_OBJ_COMMENT; // is the new message multi-level threaded? // even though we don't support it now, preserve the info @@ -2669,7 +2685,7 @@ function tag_deliver($uid,$item_id) { * Fetch stuff we need - a channel and an item */ - $u = q("select * from channel where channel_id = %d limit 1", + $u = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", intval($uid) ); if(! $u) @@ -2807,7 +2823,7 @@ function tag_deliver($uid,$item_id) { if($terms) logger('tag_deliver: post mentions: ' . print_r($terms,true), LOGGER_DATA); - $link = normalise_link($a->get_baseurl() . '/channel/' . $u[0]['channel_address']); + $link = normalise_link($u[0]['xchan_url']); if($terms) { foreach($terms as $term) { @@ -2948,7 +2964,7 @@ function tgroup_check($uid,$item) { if(! perm_is_allowed($uid,$item['author_xchan'],'tag_deliver')) return false; - $u = q("select * from channel where channel_id = %d limit 1", + $u = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d limit 1", intval($uid) ); @@ -2960,7 +2976,7 @@ function tgroup_check($uid,$item) { if($terms) logger('tgroup_check: post mentions: ' . print_r($terms,true), LOGGER_DATA); - $link = normalise_link($a->get_baseurl() . '/channel/' . $u[0]['channel_address']); + $link = normalise_link($u[0]['xchan_url']); if($terms) { foreach($terms as $term) { @@ -3183,7 +3199,7 @@ function mail_store($arr) { $arr['account_id'] = ((x($arr,'account_id')) ? intval($arr['account_id']) : 0); $arr['mid'] = ((x($arr,'mid')) ? notags(trim($arr['mid'])) : random_string()); $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['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'])) : ''); @@ -3935,7 +3951,7 @@ function drop_items($items) { // $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) { +function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = false) { $a = get_app(); @@ -3955,6 +3971,8 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { $item = $r[0]; + $linked_item = (($item['resource_id']) ? true : false); + $ok_to_delete = false; // system deletion @@ -3976,10 +3994,11 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { // 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(ITEM_DELETED), + intval(($linked_item && ! $force) ? ITEM_HIDDEN : ITEM_DELETED), intval($item['id']) ); + $arr = array('item' => $item, 'interactive' => $interactive, 'stage' => $stage); call_hooks('drop_item', $arr ); @@ -3991,10 +4010,10 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { ); if($items) { foreach($items as $i) - delete_item_lowlevel($i,$stage); + delete_item_lowlevel($i,$stage,$force); } else - delete_item_lowlevel($item,$stage); + delete_item_lowlevel($item,$stage,$force); if(! $interactive) return 1; @@ -4026,8 +4045,9 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { // It merely destroys all resources associated with an item. // Please do not use without a suitable wrapper. -function delete_item_lowlevel($item,$stage = DROPITEM_NORMAL) { +function delete_item_lowlevel($item,$stage = DROPITEM_NORMAL,$force = false) { + $linked_item = (($item['resource_id']) ? true : false); switch($stage) { case DROPITEM_PHASE2: @@ -4043,7 +4063,7 @@ function delete_item_lowlevel($item,$stage = DROPITEM_NORMAL) { case DROPITEM_PHASE1: $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), changed = '%s', edited = '%s' WHERE id = %d", - intval(ITEM_DELETED), + intval(($linked_item && ! $force) ? ITEM_HIDDEN : ITEM_DELETED), dbesc(datetime_convert()), dbesc(datetime_convert()), intval($item['id']) @@ -4052,13 +4072,24 @@ function delete_item_lowlevel($item,$stage = DROPITEM_NORMAL) { case DROPITEM_NORMAL: default: - $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), body = '', title = '', - changed = '%s', edited = '%s' WHERE id = %d", - intval(ITEM_DELETED), - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($item['id']) - ); + if($linked_item && ! $force) { + $r = q("UPDATE item SET item_restrict = ( item_restrict | %d ), + 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 = '', + changed = '%s', edited = '%s' WHERE id = %d", + intval(ITEM_DELETED), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($item['id']) + ); + } break; } @@ -4070,25 +4101,6 @@ function delete_item_lowlevel($item,$stage = DROPITEM_NORMAL) { intval($item['uid']) ); - // If item is a link to a photo/event resource, nuke all the associated photos/events - // 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", - 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']) - ); - } - } - // 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). @@ -4111,8 +4123,7 @@ function delete_item_lowlevel($item,$stage = DROPITEM_NORMAL) { intval(TERM_OBJ_POST) ); -// FIXME remove notifications for this item - + // FIXME remove notifications for this item return true; } @@ -4711,3 +4722,34 @@ function item_remove_cid($xchan_hash,$mid,$uid) { ); } } + +// Set item permissions based on results obtained from linkify_tags() +function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow, $profile_uid, $parent_item = false) { + $first_access_tag = true; + foreach($linkified as $x) { + $access_tag = $x['access_tag']; + if(($access_tag) && (! $parent_item)) { + logger('access_tag: ' . $tag . ' ' . print_r($access_tag,true), LOGGER_DATA); + if ($first_access_tag && (! get_pconfig($profile_uid,'system','no_private_mention_acl_override'))) { + + // This is a tough call, hence configurable. The issue is that one can type in a @!privacy mention + // and also have a default ACL (perhaps from viewing a collection) and could be suprised that the + // privacy mention wasn't the only recipient. So the default is to wipe out the existing ACL if a + // private mention is found. This can be over-ridden if you wish private mentions to be in + // addition to the current ACL settings. + + $str_contact_allow = ''; + $str_group_allow = ''; + $first_access_tag = false; + } + if(strpos($access_tag,'cid:') === 0) { + $str_contact_allow .= '<' . substr($access_tag,4) . '>'; + $access_tag = ''; + } + elseif(strpos($access_tag,'gid:') === 0) { + $str_group_allow .= '<' . substr($access_tag,4) . '>'; + $access_tag = ''; + } + } + } +} diff --git a/include/nav.php b/include/nav.php index a9bff4b29..a567f83c5 100644 --- a/include/nav.php +++ b/include/nav.php @@ -15,15 +15,7 @@ function nav(&$a) { $a->page['htmlhead'] .= <<< EOT <script>$(document).ready(function() { - var a; - a = $("#nav-search-text").autocomplete({ - serviceUrl: '$base/acl', - minChars: 2, - width: 250, - id: 'nav-search-text-ac', - }); - a.setOptions({ autoSubmit: true, params: { type: 'x' }}); - + $("#nav-search-text").search_autocomplete('$base/acl'); }); </script> diff --git a/include/network.php b/include/network.php index 98c411cd8..170b77d7d 100644 --- a/include/network.php +++ b/include/network.php @@ -384,7 +384,7 @@ function validate_url(&$url) { $url = 'http://' . $url; $h = @parse_url($url); - if(($h) && (dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR) || filter_var($h['host'], FILTER_VALIDATE_IP) )) { + if(($h) && (@dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR) || filter_var($h['host'], FILTER_VALIDATE_IP) )) { return true; } return false; @@ -402,7 +402,7 @@ function validate_email($addr) { return false; $h = substr($addr,strpos($addr,'@') + 1); - if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP) )) { + if(($h) && (@dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP) )) { return true; } return false; diff --git a/include/notifier.php b/include/notifier.php index e1eb0c554..06ef7bc94 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -165,6 +165,7 @@ function notifier_run($argv, $argc){ } xchan_mail_query($message[0]); $uid = $message[0]['channel_id']; + $recipients[] = $message[0]['from_xchan']; // include clones $recipients[] = $message[0]['to_xchan']; $item = $message[0]; diff --git a/include/text.php b/include/text.php index ca9c51bc3..c130a9b8a 100644 --- a/include/text.php +++ b/include/text.php @@ -6,8 +6,8 @@ require_once("include/smarty.php"); /** * This is our template processor - * - * @param string|FriendicaSmarty $s the string requiring macro substitution, + * + * @param string|FriendicaSmarty $s the string requiring macro substitution, * or an instance of FriendicaSmarty * @param array $r key value pairs (search => replace) * @return string substituted string @@ -17,10 +17,10 @@ function replace_macros($s,$r) { $arr = array('template' => $s, 'params' => $r); call_hooks('replace_macros', $arr); - + $t = $a->template_engine(); $output = $t->replace_macros($arr['template'],$arr['params']); - + return $output; } @@ -40,7 +40,7 @@ function random_string($size = 64,$type = RANDOM_STRING_HEX) { } /** - * This is our primary input filter. + * This is our primary input filter. * * The high bit hack only involved some old IE browser, forget which (IE5/Mac?) * that had an XSS attack vector due to stripping the high-bit on an 8-bit character @@ -92,10 +92,10 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') { return escape_tags($s); if($type == 'text/plain') return escape_tags($s); - $r = q("select account_id, account_roles from account left join channel on channel_account_id = account_id where channel_id = %d limit 1", + $r = q("select account_id, account_roles, channel_pageflags from account left join channel on channel_account_id = account_id where channel_id = %d limit 1", intval($channel_id) ); - if($r && ($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE)) { + if($r && (($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE))) { if(local_user() && (get_account_id() == $r[0]['account_id'])) { return $s; } @@ -105,7 +105,7 @@ function z_input_filter($channel_id,$s,$type = 'text/bbcode') { return purify_html($s); return escape_tags($s); - + } @@ -316,23 +316,23 @@ function paginate(&$a) { if($a->pager['total'] > $a->pager['itemspage']) { $o .= '<div class="pager">'; - if($a->pager['page'] != 1) + if($a->pager['page'] != 1) $o .= '<span class="pager_prev">'."<a href=\"$url".'&page='.($a->pager['page'] - 1).'">' . t('prev') . '</a></span> '; $o .= "<span class=\"pager_first\"><a href=\"$url"."&page=1\">" . t('first') . "</a></span> "; - $numpages = $a->pager['total'] / $a->pager['itemspage']; + $numpages = $a->pager['total'] / $a->pager['itemspage']; $numstart = 1; - $numstop = $numpages; + $numstop = $numpages; - if($numpages > 14) { - $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); - $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); - } + if($numpages > 14) { + $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); + $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); + } for($i = $numstart; $i <= $numstop; $i++){ - if($i == $a->pager['page']) + if($i == $a->pager['page']) $o .= '<span class="pager_current">'.(($i < 10) ? ' '.$i : $i); else $o .= "<span class=\"pager_n\"><a href=\"$url"."&page=$i\">".(($i < 10) ? ' '.$i : $i)."</a>"; @@ -350,7 +350,7 @@ function paginate(&$a) { $lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages); $o .= "<span class=\"pager_last\"><a href=\"$url"."&page=$lastpage\">" . t('last') . "</a></span> "; - if(($a->pager['total'] - ($a->pager['itemspage'] * $a->pager['page'])) > 0) + if(($a->pager['total'] - ($a->pager['itemspage'] * $a->pager['page'])) > 0) $o .= '<span class="pager_next">'."<a href=\"$url"."&page=".($a->pager['page'] + 1).'">' . t('next') . '</a></span>'; $o .= '</div>'."\r\n"; } @@ -620,7 +620,7 @@ function get_tags($s) { // Match full names against @tags including the space between first and last // We will look these up afterward to see if they are full names or not recognisable. - if(preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/',$s,$match)) { + if(preg_match_all('/(@[^ \x0D\x0A,:?\[]+ [^ \x0D\x0A@,:?\[]+)([ \x0D\x0A@,:?\[]|$)/',$s,$match)) { foreach($match[1] as $mtch) { if(strstr($mtch,"]")) { // we might be inside a bbcode color tag - leave it alone @@ -636,7 +636,7 @@ function get_tags($s) { // Otherwise pull out single word tags. These can be @nickname, @first_last // and #hash tags. - if(preg_match_all('/([@#][^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/',$s,$match)) { + if(preg_match_all('/([@#][^ \x0D\x0A,;:?\[]+)([ \x0D\x0A,;:?\[]|$)/',$s,$match)) { foreach($match[1] as $mtch) { if(strstr($mtch,"]")) { // we might be inside a bbcode color tag - leave it alone @@ -1584,13 +1584,13 @@ function mimetype_select($channel_id, $current = 'text/bbcode') { 'text/plain' ); - $r = q("select account_id, account_roles from account left join channel on account_id = channel_account_id where + $r = q("select account_id, account_roles, channel_pageflags from account left join channel on account_id = channel_account_id where channel_id = %d limit 1", intval($channel_id) ); if($r) { - if($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) { + if(($r[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($r[0]['channel_pageflags'] & PAGE_ALLOWCODE)) { if(local_user() && get_account_id() == $r[0]['account_id']) $x[] = 'application/x-php'; } @@ -2207,10 +2207,10 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) { if(strrpos($newname,'+')) { //get the id + $tagcid = substr($newname,strrpos($newname,'+') + 1); + if(strrpos($tagcid,' ')) $tagcid = substr($tagcid,0,strrpos($tagcid,' ')); - - $tagcid = substr($newname,strrpos($newname,'+') + 1); if(strlen($tagcid) < 16) $abook_id = intval($tagcid); @@ -2350,3 +2350,33 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) { return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]); } + +function linkify_tags($a, &$body, $uid) { + $str_tags = ''; + $tagged = array(); + $result = array(); + + $tags = get_tags($body); + if(count($tags)) { + foreach($tags as $tag) { + // If we already tagged 'Robert Johnson', don't try and tag 'Robert'. + // Robert Johnson should be first in the $tags array + + $fullnametagged = false; + for($x = 0; $x < count($tagged); $x ++) { + if(stristr($tagged[$x],$tag . ' ')) { + $fullnametagged = true; + break; + } + } + if($fullnametagged) + continue; + + $success = handle_tag($a, $body, $access_tag, $str_tags, ($uid) ? $uid : $profile_uid , $tag); + $results[] = array('success' => $success, 'access_tag' => $access_tag); + if($success['replaced']) $tagged[] = $tag; + } + } + return $results; +} + diff --git a/include/zot.php b/include/zot.php index c88b2a369..384769d61 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1542,15 +1542,20 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque continue; } - $r = q("select id, edited, item_flags, mid, parent_mid from item where mid = '%s' and uid = %d limit 1", + $r = q("select id, edited, item_restrict, item_flags, mid, parent_mid from item where mid = '%s' and uid = %d limit 1", dbesc($arr['mid']), intval($channel['channel_id']) ); if($r) { // We already have this post. - // Maybe it has been edited? $item_id = $r[0]['id']; - if($arr['edited'] > $r[0]['edited']) { + if($r[0]['item_restrict'] & ITEM_DELETED) { + // It was deleted locally. + $result[] = array($d['hash'],'update ignored',$channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>',$arr['mid']); + continue; + } + // Maybe it has been edited? + elseif($arr['edited'] > $r[0]['edited']) { $arr['id'] = $r[0]['id']; $arr['uid'] = $channel['channel_id']; update_imported_item($sender,$arr,$channel['channel_id']); @@ -2363,6 +2368,9 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) { logger('build_sync_packet'); + if($packet) + logger('packet: ' . print_r($packet,true),LOGGER_DATA); + if(! $uid) $uid = local_user(); |