is_installed() ) {
foreach( WPF()->board->get_active_boardids() as $boardid ) {
register_nav_menus(
[
str_replace( '_', '-', WPF()->generate_prefix( $boardid ) ) . 'menu' => esc_html__(
'wpForo Menu',
'wpforo'
) . ( $boardid ? ' #' . $boardid : '' ),
]
);
}
}
} );
add_filter(
'wp_get_nav_menu_items',
function( $items ) {
if( ! wpforo_is_admin() ) {
foreach( $items as $key => $item ) {
if( isset( $item->url ) ) {
if( strpos( (string) $item->url, '%wpforo-' ) !== false ) {
// Extract shortcode and any query parameters (e.g., %wpforo-profile-activity?boardid=2%)
$url_part = trim( str_replace( [ 'https://', 'http://', '/', '%' ], '', (string) $item->url ) );
$query_params = [];
if( strpos( $url_part, '?' ) !== false ) {
list( $shortcode, $query_string ) = explode( '?', $url_part, 2 );
parse_str( $query_string, $query_params );
} else {
$shortcode = $url_part;
}
if( isset( WPF()->tpl->menu ) && isset( WPF()->tpl->menu[ $shortcode ] ) ) {
if( isset( WPF()->tpl->menu[ $shortcode ]['href'] ) ) {
$url = WPF()->tpl->menu[ $shortcode ]['href'];
// Append query parameters (like boardid) if present
if( ! empty( $query_params ) ) {
$url = add_query_arg( $query_params, $url );
}
// Auto-append current boardid on multi-board sites (except home).
// Skip if boardid is already present (admin-provided or built-in).
if(
$shortcode !== 'wpforo-home'
&& is_wpforo_multiboard()
&& ! isset( $query_params['boardid'] )
&& strpos( (string) $url, 'boardid=' ) === false
) {
$current_boardid = (int) WPF()->board->get_current( 'boardid' );
if( $current_boardid > 0 ) {
$url = add_query_arg( 'boardid', $current_boardid, $url );
}
}
$item->url = $url;
}
if( wpfval( WPF()->tpl->menu[ $shortcode ], 'is_active' ) || ( isset(
WPF()->tpl->menu[ $shortcode ]['attr']
) && strpos(
(string) WPF()->tpl->menu[ $shortcode ]['attr'],
'wpforo-active'
) !== false ) ) {
$item->classes[] = 'wpforo-active';
}
} else {
unset( $items[ $key ] );
}
}
}
}
}
return $items;
},
1
);
function wpforo_menu_nofollow_items( $item_output, $item, $depth, $args ) {
//if( isset($item->url) && strpos((string) $item->url, '?foro') !== FALSE ) {
//$item_output = str_replace('board->get_current( 'boardid' );
if( $boardid <= 0 ) return $profile_url;
return add_query_arg( 'boardid', $boardid, $profile_url );
}
/**
* Detects the special anonymous email mask used by wpforo_anonymous_posting plugin.
* Pattern: anonymous+topic{topicid}-{number}@example.com
*/
function wpforo_is_anonymous_mask_email( $email ): bool {
if( ! is_string( $email ) || $email === '' ) return false;
return (bool) preg_match( '/^anonymous\+topic\d+-\d+@example\.com$/', $email );
}
/**
* Convenience helper to check if a member/guest array is anonymized by the plugin.
*/
function wpforo_is_anonymous_mask_member( $member ): bool {
if( is_array( $member ) ) {
$email = wpfval( $member, 'user_email' );
return wpforo_is_anonymous_mask_email( $email );
}
return false;
}
function wpforo_profile_plugin_menu( $user ) {
$userid = $user['userid'];
$menu_html = '';
if( $url = wpforo_has_shop_plugin() ) {
$menu_html .= '';
}
if( $url = wpforo_has_profile_plugin( $userid ) ) {
$menu_html .= '';
}
$menu_html = apply_filters( 'wpforo_profile_top_bar', $menu_html, $userid );
if( $menu_html ) echo '';
}
//add_action( 'wpforo_template_profile_action_buttons_left', 'wpforo_profile_plugin_menu' );
function wpforo_post_edited( $post, $echo = true ) {
$edit_html = '';
if( ! empty( $post ) ) {
$created = wpforo_date( $post['created'], 'd/m/Y g:i a', false );
$modified = wpforo_date( $post['modified'], 'd/m/Y g:i a', false );
if( isset( $modified ) && $created != $modified ) {
if( $post['is_first_post'] && wpforo_setting( 'posting', 'edit_topic' ) ) {
$edit_html = WPF()->activity->build( 'topic', $post['topicid'], 'edit_topic' );
} elseif( wpforo_setting( 'posting', 'edit_post' ) ) {
$edit_html = WPF()->activity->build( 'post', $post['postid'], 'edit_post' );
}
$edit_html = $edit_html ? sprintf( '%s
', $edit_html ) : '';
}
}
$edit_html = apply_filters( 'wpforo_post_edited', $edit_html, $post );
if( $echo ) {
echo $edit_html;
} else {
return $edit_html;
}
}
function wpforo_hide_title( $title, $id = 0 ) {
if( is_page( $id ) && in_the_loop() && is_wpforo_page() && $id === WPF()->board->get_current(
'pageid'
) && ! wpforo_setting( 'components', 'page_title' ) ) {
$title = '';
}
return $title;
}
add_filter( 'the_title', 'wpforo_hide_title', 10, 2 );
function wpforo_validate_gravatar( $email ) {
$hashkey = md5( strtolower( trim( (string) $email ) ) );
$uri = 'http://www.gravatar.com/avatar/' . $hashkey . '?d=404';
$data = wp_cache_get( $hashkey );
if( false === $data ) {
$response = wp_remote_head( $uri );
if( is_wp_error( $response ) ) {
$data = 'not200';
} else {
$data = $response['response']['code'];
}
wp_cache_set( $hashkey, $data, $group = '', $expire = 60 * 5 );
}
if( $data == '200' ) {
return true;
} else {
return false;
}
}
function wpforo_member_title( $member = [], $echo = true, $before = '', $after = '', $exclude = [] ) {
// Hide user titles for anonymized masked emails
if( wpforo_is_anonymous_mask_member( $member ) ) {
if( $echo ) echo '';
return '';
}
$title = [];
if( empty( $member ) || ! $member['groupid'] ) return '';
$rating_title_ug_enabled = in_array( $member['groupid'], wpforo_setting( 'rating', 'rating_title_ug' ), true );
$usergroup_title_ug_enabled = in_array( $member['groupid'], wpforo_setting( 'profiles', 'title_groupids' ), true );
if( ! in_array( 'rating-title', $exclude, true ) && wpforo_setting(
'rating',
'rating_title'
) && $rating_title_ug_enabled && isset( $member['rating']['title'] ) ) {
$title[] = '' . esc_html( $member['rating']['title'] ) . ' ';
}
if( ! in_array( 'custom-title', $exclude, true ) && empty( $title ) && wpforo_setting(
'profiles',
'custom_title_is_on'
) ) {
$title[] = '' . wpforo_phrase( $member['title'], false ) . ' ';
} elseif( in_array( 'custom-fields', $exclude, true ) ) {
$before = $after = '';
}
if( ! in_array( 'custom-fields', $exclude, true ) ) {
$fields = apply_filters( 'wpforo_member_info_custom_fields', [], $member );
if( ! empty( $fields ) ) {
$count = count( $fields );
$i = 1;
if( $count ) {
$title[] = apply_filters(
'wpforo_member_custom_field_separator',
' ',
$member
);
}
foreach( $fields as $field ) {
$title[] = '' . $field['value'] . ( $count !== $i ? $after : '' ) . ' ';
$i ++;
}
}
$before = $after = '';
}
if( ! in_array( 'usergroup', $exclude, true ) && $usergroup_title_ug_enabled ) {
$class = '';
if( $member['groupid'] === 1 ) $class = ' wpfbr-b wpfcl-b';
if( $member['groupid'] === 2 ) $class = ' wpfbr-5 wpfcl-5';
if( $member['groupid'] === 4 ) $class = ' wpfbg-2 wpfcl-3';
if( ! in_array( $member['groupid'], [ 1, 2, 4 ], true ) ) $class = ' wpfbr-7';
$title[] = '' . esc_html(
$member['group_name']
) . ' ';
}
if( ! in_array( 'usergroup', $exclude, true ) ) {
$groupids = array_intersect(
$member['secondary_groupids'],
wpforo_setting( 'profiles', 'title_secondary_groupids' )
);
$secondary_group_names = $groupids ? WPF()->usergroup->get_secondary_group_names( $groupids ) : [];
if( $secondary_group_names ) {
$title[] = '' . esc_html( implode( ', ', $secondary_group_names ) ) . ' ';
}
}
$title_html = '';
if( ! empty( $title ) ) {
$title_html = $before . implode( ' ', $title ) . $after;
$title_html = apply_filters( 'wpforo_member_title', $title_html, $member );
}
if( $echo ) echo $title_html;
return $title_html;
}
function wpforo_member_badge( $member = [], $sep = '', $type = 'full' ) {
// Hide badges for anonymized masked emails
if( wpforo_is_anonymous_mask_member( $member ) ) return;
$rating_badge_ug_enabled = in_array( $member['groupid'], wpforo_setting( 'rating', 'rating_badge_ug' ), true );
if( wpforo_setting( 'rating', 'rating' ) && $rating_badge_ug_enabled && isset( $member['rating']['level'] ) ): ?>
member->rating_badge( $member['rating']['level'], $type ); ?>
';
}
if( $bracket ) $nicename .= '(';
$nicename .= $prefix . urldecode( (string) $member['user_nicename'] );
if( $bracket ) $nicename .= ')';
if( $wrap ) {
$nicename .= '';
}
$nicename = apply_filters( 'wpforo_member_nicename', $nicename, $member );
if( $echo ) {
echo $nicename;
} else {
return $nicename;
}
}
function wpforo_get_body_classes() {
$classes = [
'wpf-' . esc_attr( wpforo_setting( 'styles', 'color_style' ) ),
'wpft-' . esc_attr( WPF()->current_object['template'] ),
( WPF()->current_userid ? 'wpf-auth' : 'wpf-guest' ),
'wpfu-group-' . WPF()->current_user_groupid,
'wpf-theme-' . WPF()->tpl->theme,
'wpf-is_standalone-' . (int) WPF()->board->get_current( 'is_standalone' ),
'wpf-boardid-' . WPF()->board->get_current( 'boardid' ),
'is_wpforo_page-' . (int) is_wpforo_page(),
'is_wpforo_url-' . (int) is_wpforo_url(),
'is_wpforo_shortcode_page-' . (int) is_wpforo_shortcode_page(),
];
if( is_wpforo_page() ) $classes[] = 'wpforo';
return apply_filters( 'wpforo_get_body_classes', $classes );
}
add_action( 'wpforo_wrap_class', function() {
echo implode( ' ', wpforo_get_body_classes() );
} );
add_filter( 'body_class', function( $classes ) {
return array_merge( $classes, wpforo_get_body_classes() );
} );
function wpforo_get_postmeta( $postid, $metakeys = '', $single = false ) {
return WPF()->postmeta->get_postmeta( $postid, $metakeys, $single );
}
###############################################################################
########################## THEME API FUNCTIONS ################################
###############################################################################
function _wpforo_post( $postid, $var = 'item' ) {
$post = ( $var === 'item' ) ? [] : null;
if( ! $postid ) return $post;
if( $var === 'url' ) {
$post['url'] = WPF()->post->get_url( $postid );
} elseif( $var === 'full_url' ) {
$post['full_url'] = WPF()->post->get_full_url( $postid );
} elseif( $var === 'short_url' ) {
$post['short_url'] = WPF()->post->get_short_url( $postid );
} elseif( $var === 'is_answered' ) {
$post['is_answered'] = WPF()->post->is_answered( $postid );
} elseif( $var === 'likes_count' ) {
$post['likes_count'] = WPF()->reaction->get_post_reactions_count( $postid );
} elseif( $var === 'likers_usernames' ) {
$post['likers_usernames'] = WPF()->reaction->get_post_reactions_user_dnames( $postid );
} else {
$post = WPF()->post->_get_post( $postid, false );
if( ! empty( $post ) ) {
$post['url'] = WPF()->post->get_url( $post );
$post['full_url'] = WPF()->post->get_full_url( $post );
$post['short_url'] = WPF()->post->get_short_url( $post );
$post['is_answered'] = WPF()->post->is_answered( $postid );
$post['likes_count'] = WPF()->reaction->get_post_reactions_count( $postid );
$post['likers_usernames'] = WPF()->reaction->get_post_reactions_user_dnames( $postid );
}
}
if( $var !== 'item' ) $post = wpfkey( $post, $var ) ? $post[ $var ] : wpforo_get_postmeta( $postid, $var, true );
return apply_filters( 'wpforo_post', $post, $var );
}
function wpforo_post( $postid, $var = 'item', $echo = false ) {
$post = ( $var === 'item' ) ? [] : null;
if( ! $postid ) return $post;
$cache = WPF()->cache->on( 'post' );
if( $cache ) $post = WPF()->cache->get_item( $postid, 'post' );
if( empty( $post ) ) {
$post = [];
if( ! $cache && $var === 'url' ) {
$post['url'] = WPF()->post->get_url( $postid );
} elseif( ! $cache && $var === 'full_url' ) {
$post['full_url'] = WPF()->post->get_full_url( $postid );
} elseif( ! $cache && $var === 'short_url' ) {
$post['short_url'] = WPF()->post->get_short_url( $postid );
} elseif( ! $cache && $var === 'is_answered' ) {
$post['is_answered'] = WPF()->post->is_answered( $postid );
} elseif( ! $cache && $var === 'likes_count' ) {
$post['likes_count'] = WPF()->reaction->get_post_reactions_count( $postid );
} elseif( ! $cache && $var === 'likers_usernames' ) {
$post['likers_usernames'] = WPF()->reaction->get_post_reactions_user_dnames( $postid );
} else {
$post = WPF()->post->get_post( $postid );
if( ! empty( $post ) ) {
$post['url'] = WPF()->post->get_url( $post );
$post['full_url'] = WPF()->post->get_full_url( $post );
$post['short_url'] = WPF()->post->get_short_url( $post );
$post['is_answered'] = WPF()->post->is_answered( $postid );
$post['likes_count'] = WPF()->reaction->get_post_reactions_count( $postid );
$post['likers_usernames'] = WPF()->reaction->get_post_reactions_user_dnames( $postid );
if( ! empty( $post ) ) {
$cache_item = [ $postid => $post ];
WPF()->cache->create( 'item', $cache_item, 'post' );
}
}
}
}
if( $var !== 'item' ) $post = wpfkey( $post, $var ) ? $post[ $var ] : wpforo_get_postmeta( $postid, $var, true );
if( $echo && is_scalar( $post ) ) echo $post;
return apply_filters( 'wpforo_post', $post, $var );
}
function _wpforo_topic( $topicid, $var = 'item' ) {
$topic = ( $var === 'item' ) ? [] : null;
if( ! $topicid ) return $topic;
if( $var === 'url' ) {
$topic['url'] = WPF()->topic->_get_url( $topicid );
} elseif( $var === 'full_url' ) {
$topic['full_url'] = WPF()->topic->get_full_url( $topicid );
} elseif( $var === 'short_url' ) {
$topic['short_url'] = WPF()->topic->get_short_url( $topicid );
} else {
$topic = WPF()->topic->_get_topic( $topicid, false );
if( ! empty( $topic ) ) {
$topic['url'] = WPF()->topic->_get_url( $topic );
$topic['full_url'] = WPF()->topic->get_full_url( $topic );
$topic['short_url'] = WPF()->topic->get_short_url( $topic );
}
}
if( $var !== 'item' ) {
if( $var === 'body' ) {
$topic = wpforo_bigintval( wpfval( $topic, 'first_postid' ) ) ? _wpforo_post(
$topic['first_postid'],
'body'
) : '';
} else {
$topic = wpfval( $topic, $var );
}
}
return apply_filters( 'wpforo_topic', $topic, $var );
}
function wpforo_topic( $topicid, $var = 'item', $echo = false ) {
$topic = ( $var === 'item' ) ? [] : null;
if( ! $topicid ) return $topic;
$cache = WPF()->cache->on( 'topic' );
if( $cache ) $topic = WPF()->cache->get_item( $topicid, 'topic' );
if( empty( $topic ) ) {
$topic = [];
if( ! $cache && $var === 'url' ) {
$topic['url'] = WPF()->topic->get_url( $topicid );
} elseif( ! $cache && $var === 'full_url' ) {
$topic['full_url'] = WPF()->topic->get_full_url( $topicid );
} elseif( ! $cache && $var === 'short_url' ) {
$topic['short_url'] = WPF()->topic->get_short_url( $topicid );
} else {
$topic = WPF()->topic->get_topic( $topicid );
if( ! empty( $topic ) ) {
$topic['url'] = WPF()->topic->get_url( $topic );
$topic['full_url'] = WPF()->topic->get_full_url( $topic );
$topic['short_url'] = WPF()->topic->get_short_url( $topic );
if( ! empty( $topic ) ) {
$cache_item = [ $topicid => $topic ];
WPF()->cache->create( 'item', $cache_item, 'topic' );
}
}
}
}
if( $var !== 'item' ) {
if( $var === 'body' ) {
$topic = wpforo_post( $topic['first_postid'], 'body' );
} else {
$topic = wpfval( $topic, $var );
}
}
if( $echo && is_scalar( $topic ) ) echo $topic;
return apply_filters( 'wpforo_topic', $topic, $var );
}
function _wpforo_forum( $forumid, $var = 'item' ) {
$forum = ( $var === 'item' ) ? [] : null;
if( ! $forumid ) return $forum;
$forum = WPF()->forum->_get_forum( $forumid );
if( ! empty( $forum ) ) {
if( in_array( $var, [ 'childs', 'counts' ], true ) ) {
$forum['childs'] = WPF()->forum->get_childs( $forumid );
$forum['childs'][] = $forumid;
if( $var === 'counts' ) $forum['counts'] = WPF()->forum->get_counts( $forum['childs'] );
}
}
if( $var !== 'item' ) $forum = wpfval( $forum, $var );
return apply_filters( 'wpforo_forum', $forum, $var );
}
function wpforo_forum( $forumid, $var = 'item', $echo = false ) {
$forum = ( $var === 'item' ) ? [] : null;
$cache = WPF()->cache->on( 'forum' );
if( ! $forumid ) return $forum;
if( $cache ) $forum = WPF()->cache->get_item( $forumid, 'forum' );
if( empty( $forum ) ) {
$forum = [];
if( ! $cache && in_array( $var, [ 'childs', 'counts' ], true ) ) {
$forum['childs'] = WPF()->forum->get_childs( $forumid );
$forum['childs'][] = $forumid;
if( $var === 'counts' ) $forum['counts'] = WPF()->forum->get_counts( $forum['childs'] );
} else {
$forum = WPF()->forum->get_forum( $forumid );
if( ! empty( $forum ) ) {
if( $cache ) {
$forum['childs'] = WPF()->forum->get_childs( $forum['forumid'] );
$forum['childs'][] = $forum['forumid'];
$forum['counts'] = WPF()->forum->get_counts( $forum['childs'] );
}
if( ! empty( $forum ) ) {
$cache_item = [ $forumid => $forum ];
WPF()->cache->create( 'item', $cache_item, 'forum' );
}
}
}
}
if( $var !== 'item' ) $forum = wpfval( $forum, $var );
if( $echo && is_scalar( $forum ) ) echo $forum;
return apply_filters( 'wpforo_forum', $forum, $var );
}
function wpforo_member( $object, $var = 'item', $echo = false ) {
$member = null;
if( ! empty( $object ) ) {
if( is_array( $object ) && ! wpforo_bigintval( wpfval( $object, 'userid' ) ) ) {
//If there is no user ID or it's 0 generate guest user array
$member = WPF()->member->get_guest( $object );
} else {
//If there is a userid get user array
$userid = ( is_array( $object ) && isset( $object['userid'] ) ) ? intval( $object['userid'] ) : intval(
$object
);
$member = WPF()->member->get_member( $userid );
// If userid exists but the user is removed from wp_users generate guest user array
if( empty( $member ) ) {
$object = is_array( $object ) ? $object : [];
$member = WPF()->member->get_guest( $object );
}
}
$member = apply_filters( 'wpforo_get_member', $member );
if( $var !== 'item' && $var ) {
if( $member ) {
if( $var === 'secondary_group_names' ) {
$secondary_group_names = [];
if( $secondary_groupids = (array) wpfval( $member, 'secondary_groupids' ) ) {
$secondary_group_names = array_map( function( $groupid ) {
$group = WPF()->usergroup->get_usergroup( $groupid );
return wpfval( $group, 'name' );
}, $secondary_groupids );
$secondary_group_names = array_filter( $secondary_group_names );
}
$member = $secondary_group_names;
} elseif( $var === 'group_names' ) {
$group_names = [];
if( $groupids = (array) wpfval( $member, 'groupids' ) ) {
$group_names = array_map( function( $groupid ) {
$group = WPF()->usergroup->get_usergroup( $groupid );
return wpfval( $group, 'name' );
}, $groupids );
$group_names = array_filter( $group_names );
}
$member = $group_names;
} else {
$member = wpfval( $member, $var );
}
} else {
$member = null;
}
}
}
if( $echo ) echo $member;
return apply_filters( 'wpforo_member', $member, $var );
}
function wpforo_current_usermeta( $key ) {
if( wpfkey( WPF()->current_usermeta, $key ) ) {
if( wpfkey( WPF()->current_usermeta[ $key ], 0 ) ) {
$meta = maybe_unserialize( WPF()->current_usermeta[ $key ][0] );
return $meta;
}
}
}
function _wpforo_tag( $tagid, $var = 'item' ) {
$tag = ( $var == 'item' ) ? [] : null;
if( ! $tagid ) return $tag;
if( $var === 'url' && wpfval( $tag, 'tag' ) ) {
$tag['url'] = wpforo_home_url() . '?wpfin=tag&wpfs=' . urlencode( $tag['tag'] );
} else {
$tag = WPF()->topic->get_tag( $tagid );
if( ! empty( $tag ) ) $tag['url'] = wpforo_home_url() . '?wpfin=tag&wpfs=' . urlencode( $tag['tag'] );
}
if( $var !== 'item' ) $tag = wpfval( $tag, $var );
return $tag;
}
function wpforo_tag( $tagid, $var = 'item', $echo = false ) {
$tag = ( $var == 'item' ) ? [] : null;
if( ! $tagid ) return $tag;
$cache = WPF()->cache->on( 'tag' );
if( $cache ) $tag = WPF()->cache->get_item( md5( $tagid ), 'tag' );
if( empty( $tag ) ) {
$tag = [];
if( ! $cache && $var == 'url' && wpfval( $tag, 'tag' ) ) {
$tag['url'] = wpforo_home_url() . '?wpfin=tag&wpfs=' . urlencode( $tag['tag'] );
} else {
$tag = WPF()->topic->get_tag( $tagid );
if( ! empty( $tag ) ) {
$tag['url'] = wpforo_home_url() . '?wpfin=tag&wpfs=' . urlencode( $tag['tag'] );
if( ! empty( $tag ) ) {
$cache_item = [ md5( $tagid ) => $tag ];
WPF()->cache->create( 'item', $cache_item, 'tag' );
}
}
}
}
if( $var !== 'item' ) $tag = wpfval( $tag, $var );
if( $echo && is_scalar( $tag ) ) echo $tag;
return $tag;
}
function wpforo_member_link( $user, $prefix = '', $size = 30, $class = '', $echo = true, $content = '', $attr = '' ) {
$dname = wpforo_user_dname( $user );
$title = $dname ? sprintf( 'title="%1$s"', esc_attr( $dname ) ) : '';
// Append is_guest class when userid == 0 to allow styling (e.g., disable hover effects)
$is_guest = (int) wpfval( $user, 'userid' ) === 0;
$classes = trim( (string) $class );
if( $is_guest ) {
$classes = $classes ? ( $classes . ' is_guest' ) : 'is_guest';
}
$class_attr = $classes ? sprintf( 'class="%1$s"', esc_attr( $classes ) ) : '';
$color = wpfval( $user, 'group_color' ) ? sprintf( 'color: %1$s', $user['group_color'] ) : '';
if( $content === 'avatar' ) {
$ret = wpforo_user_avatar( $user, $size, $attr );
} elseif( trim( (string) $content ) ) {
$ret = $content;
} else {
$ret = ( strpos( (string) $prefix, '%s' ) !== false ? sprintf(
wpforo_phrase( $prefix, false ),
esc_html( wpforo_text( $dname, $size, false ) )
) : ( $prefix ? wpforo_phrase( $prefix, false ) . ' ' : '' ) . esc_html(
wpforo_text( $dname, $size, false )
) );
}
if( apply_filters( 'wpforo_member_link_clickable', true, $user ) && wpfval( $user, 'userid' ) && wpfval(
$user,
'profile_url'
) ) {
$ret = sprintf(
' %5$s ',
esc_url( (string) $user['profile_url'] ),
$color,
$class_attr,
$title,
$ret
);
} else {
$ret = sprintf(
'%4$s ',
$color,
$class_attr,
$title,
$ret
);
}
if( $echo ) echo $ret;
return $ret;
}
add_shortcode( 'wpforo-lostpassword', function() {
$ob_exists = function_exists( 'ob_start' ) && function_exists( 'ob_get_clean' );
if( $ob_exists ) ob_start();
?>
tpl->get_template_path( 'login' ) ) include( $path );
return ( $ob_exists ) ? trim( (string) ob_get_clean() ) : '';
} );
#############################################################################################
/**
* Generates according page form fields using tpl->form_fields() function
*
* @param array $fields arguments
* @param boolean $echo
*
* @return string form fields HTML
* @since 1.4.0
*
*/
function wpforo_fields( $fields, $echo = true ) {
if( empty( $fields ) ) return '';
$fields = apply_filters( 'wpforo_form_fields', $fields );
$html = WPF()->form->build( $fields );
if( $echo ) {
echo $html;
} else {
return $html;
}
}
function wpforo_user_avatar( $user, $size = 96, $attr = '', $lastmod = false ) {
$img = WPF()->member->get_avatar( $user, $size, $attr );
if( $lastmod && ( $url = wpforo_avatar_url( $img ) ) && strpos( (string) $url, '?' ) === false ) {
$img = str_replace( $url, $url . '?lm=' . time(), $img );
}
return $img;
}
function wpforo_signature( $member, $args = [] ) {
if( is_numeric( $member ) ) $member = wpforo_member( $member );
if( wpfkey( $member, 'rating', 'level' ) ) {
$min_level = apply_filters( 'wpforo_min_rating_level_for_signature', 1 );
if( $min_level && (int) $member['rating']['level'] < $min_level ) return '';
}
if( WPF()->current_userid != wpfval( $member, 'userid' ) && ! WPF()->usergroup->can( 'vms' ) ) return '';
$signature = '';
$default = [ 'nofollow' => 1, 'kses' => 1, 'echo' => 1 ];
if( empty( $args ) ) {
$args = $default;
} else {
$args = wpforo_parse_args( $args, $default );
}
if( is_array( $member ) && ! empty( $member ) ) {
$signature = ( isset( $member['signature'] ) ) ? $member['signature'] : '';
} elseif( is_string( $member ) ) {
$signature = $member;
}
$signature = stripslashes( (string) $signature );
if( ! empty( $args ) ) {
$kses = isset( $args['kses'] ) ? $args['kses'] : 1;
$nofollow = isset( $args['nofollow'] ) ? $args['nofollow'] : 1;
if( isset( $kses ) && $kses ) $signature = wpforo_kses( $signature, 'user_description' );
if( isset( $nofollow ) && $nofollow ) $signature = wpforo_nofollow_tag( $signature );
} else {
$signature = wpforo_nofollow( wpforo_kses( $signature, 'user_description' ) );
}
$length = apply_filters( 'wpforo_signature_length', 0 );
$signature = wpforo_text( $signature, $length, false, false, false, false );
$signature = wpautop( $signature );
if( $args['echo'] ) {
echo $signature;
} else {
return $signature;
}
}
function wpforo_register_fields() {
$fields = WPF()->member->get_register_fields();
do_action( 'wpforo_register_page_start', $fields );
return $fields;
}
function wpforo_account_fields() {
$fields = WPF()->member->get_account_fields();
do_action( 'wpforo_account_page_start', $fields );
return $fields;
}
function wpforo_profile_fields() {
$fields = WPF()->member->get_profile_fields();
do_action( 'wpforo_profile_page_start', $fields );
return $fields;
}
function wpforo_search_fields() {
$fields = WPF()->member->get_search_fields();
do_action( 'wpforo_search_page_start', $fields );
if( wpforo_setting( 'members', 'search_type' ) === 'search' ) {
$fields = [
[
[
[
'type' => 'search',
'isDefault' => 1,
'isRemovable' => 0,
'isRequired' => 0,
'isEditable' => 1,
'class' => 'wpf-member-search-field',
'label' => wpforo_phrase( 'Find a member', false ),
'title' => wpforo_phrase( 'Find a member', false ),
'placeholder' => wpforo_phrase( 'Display Name or Nicename', false ),
'faIcon' => 'fas fa-search',
'name' => 'wpfms',
'cantBeInactive' => [ 'search' ],
'can' => '',
'isSearchable' => 1,
],
],
],
];
}
return $fields;
}
function wpforo_topic_types( $topic, $class = true, $echo = true ) {
$topic_types = [];
if( wpfval( $topic, 'type' ) ) $topic_types[] = 'sticky';
if( wpfval( $topic, 'closed' ) ) $topic_types[] = 'closed';
if( wpfval( $topic, 'private' ) ) $topic_types[] = 'private';
if( wpfval( $topic, 'solved' ) ) $topic_types[] = 'solved';
if( wpfval( $topic, 'status' ) ) $topic_types[] = 'unapproved';
$types = $class ? ( ! empty( $topic_types ) ? trim(
'wpf-tt-' . implode( ' wpf-tt-', $topic_types ),
','
) : '' ) : $topic_types;
if( $echo ) echo $types;
return $types;
}
function wpforo_unread( $itemid, $item, $echo = true, $postid = 0 ) {
$class = '';
$unread = false;
$login = is_user_logged_in();
$login = apply_filters( 'wpforo_unread_logging_for_guests', $login );
if( $login ) {
if( $item === 'forum' ) {
$class = 'wpf-unread-forum';
$unread = WPF()->log->unread( $itemid, 'forum' );
$unread = apply_filters( 'wpforo_unread_forum', $unread, $itemid );
} elseif( $item === 'topic' ) {
$class = 'wpf-unread-topic';
$unread = WPF()->log->unread( $itemid, 'topic' );
$unread = apply_filters( 'wpforo_unread_topic', $unread, $itemid );
} elseif( $item === 'post' ) {
$class = 'wpf-unread-post';
$unread = WPF()->log->unread( $itemid, 'post', $postid );
$unread = apply_filters( 'wpforo_unread_post', $unread, $itemid, $postid );
}
}
$class = ( $unread ) ? apply_filters( 'wpforo_unread_class', $class, $itemid, $item ) : '';
if( $echo ) echo $class;
return $class;
}
function wpforo_unread_forum( $logid, $return = 'class', $echo = true ) {
$unread = WPF()->log->unread( $logid, 'forum' );
if( $return === 'class' ) {
$log = $unread ? 'wpf_forum_unread' : '';
} else {
$log = (bool) $unread;
}
if( $echo ) echo $log;
return $log;
}
function wpforo_unread_topic( $logid, $return = 'class', $echo = true ) {
$unread = WPF()->log->unread( $logid, 'topic' );
if( $return === 'class' ) {
$log = $unread ? 'wpf_topic_unread' : '';
} else {
$log = (bool) $unread;
}
if( $echo ) echo $log;
return $log;
}
if( ! function_exists( 'custom_wpforo_get_account_fields' ) ) {
function custom_wpforo_get_account_fields( $fields ) {
$hide = [
'user_email',
'user_nicename',
];
foreach( $fields as $row_key => $row ) {
foreach( $row as $col_key => $col ) {
foreach( $col as $key => $field ) {
if( in_array( $field['fieldKey'], $hide ) ) {
unset( $fields[ $row_key ][ $col_key ][ $key ] );
}
}
}
}
return $fields;
}
}
function wpforo_moderation_tools() {
if( empty( WPF()->current_object['forumid'] ) || empty( WPF()->current_object['topicid'] ) ) return;
?>
perm->forum_can( 'mt' ) ) {
$posts = (int) wpfval( WPF()->current_object, 'topic', 'posts' );
$tabs[] = [
'title' => wpforo_phrase( 'Move Topic', false ),
'id' => 'topic_move_form',
'class' => 'wpft-move',
'icon' => 'far fa-share-square',
];
if( $posts > 1 ) {
$tabs[] = [
'title' => wpforo_phrase( 'Move Reply', false ),
'id' => 'reply_move_form',
'class' => 'wpft-reply-move',
'icon' => 'far fa-share-square',
];
}
$tabs[] = [
'title' => wpforo_phrase( 'Merge Topics', false ),
'id' => 'topic_merge_form',
'class' => 'wpft-merge',
'icon' => 'fas fa-code-branch',
];
if( $posts > 1 ) {
$tabs[] = [
'title' => wpforo_phrase( 'Split Topic', false ),
'id' => 'topic_split_form',
'class' => 'wpft-split',
'icon' => 'fas fa-cut',
];
}
}
WPF()->tpl->topic_moderation_tabs( $tabs );
?>
'',
'title' => '',
'content' => '',
'component' => 'community',
'type' => '',
'primary_link' => '',
'user_id' => '',
'item_id' => '',
'date_recorded' => '',
];
$args = wpforo_parse_args( $args, $default );
//BuddyPress Member Activity
if( wpforo_setting( 'buddypress', 'activity' ) && function_exists( 'wpforo_bp_activity' ) ) {
wpforo_bp_activity( $args );
}
}
function wpforo_activity_delete( $args = [] ) {
$default = [
'action' => '',
'title' => '',
'content' => '',
'component' => 'community',
'type' => '',
'primary_link' => '',
'user_id' => '',
'item_id' => '',
'date_recorded' => '',
];
$args = wpforo_parse_args( $args, $default );
//Delete BuddyPress Member Activity
if( wpforo_setting( 'buddypress', 'activity' ) && function_exists( 'wpforo_bp_activity_delete' ) ) {
wpforo_bp_activity_delete( $args );
}
}
function wpforo_activity_content( $item = [] ) {
$args = [];
if( empty( $item ) ) return false;
if( ( isset( $item['status'] ) && $item['status'] ) || ( isset( $item['private'] ) && $item['private'] ) ) return false;
if( isset( $item['forumid'] ) && $item['forumid'] ) {
$private_for_usergroups = [ 3, 4, 5 ];
$private_for_usergroups = apply_filters( 'wpforo_activity_private_for_usergroups', $private_for_usergroups );
if( ! empty( $private_for_usergroups ) && WPF()->forum->private_forum(
$item['forumid'],
$private_for_usergroups
) ) {
return false;
}
}
if( isset( $item['first_postid'] ) && $item['first_postid'] ) {
$args['item_id'] = $item['first_postid'];
} elseif( isset( $item['postid'] ) && $item['postid'] ) {
$args['item_id'] = $item['postid'];
}
$args['user_id'] = ( isset( $item['userid'] ) && $item['userid'] ) ? $item['userid'] : $args['user_id'] = WPF()->current_userid;
$member = wpforo_member( $args['user_id'] );
if( isset( $item['topicurl'] ) ) {
$args['type'] = 'wpforo_topic';
$args['content'] = ( wpfval( $item, 'body' ) ) ? $item['body'] : '';
$args['primary_link'] = $item['topicurl'];
if( isset( $item['title'] ) ) $args['title'] = $item['title'];
if( $args['title'] ) $args['title'] = ' "' . esc_html( $args['title'] ) . '"';
$args['action'] = sprintf( wpforo_phrase( '%s posted a new topic %s', false ), '', '' );
} elseif( isset( $item['posturl'] ) ) {
$args['type'] = 'wpforo_post';
$args['content'] = ( wpfval( $item, 'body' ) ) ? $item['body'] : '';
$args['primary_link'] = $item['posturl'];
if( isset( $item['title'] ) ) $args['title'] = preg_replace( '|^.+?:\s*|is', '', (string) $item['title'] );
if( $args['title'] ) $args['title'] = ' "' . esc_html( $args['title'] ) . '"';
$args['action'] = sprintf( wpforo_phrase( '%s replied to the topic %s', false ), '', '' );
}
if( $args['content'] ) {
$content_words = explode( ' ', $args['content'] );
$content_words = count( $content_words );
$content_words_cut = apply_filters( 'wpforo_activity_content_words', '40' );
if( (int) $content_words_cut < (int) $content_words && $args['primary_link'] ) {
$more = '... ' . wpforo_phrase(
'read more',
false
) . '» ';
$args['content'] = wp_trim_words( $args['content'], 40, $more );
}
}
wpforo_activity( $args );
}
function wpforo_activity_content_delete( $item = [] ) {
$args = [];
if( empty( $item ) ) return false;
if( wpfval( $item, 'first_postid' ) ) {
$args['item_id'] = $item['first_postid'];
$args['type'] = 'wpforo_topic';
} elseif( wpfval( $item, 'is_first_post' ) ) {
$args['item_id'] = $item['postid'];
$args['type'] = 'wpforo_topic';
} elseif( wpfval( $item, 'postid' ) ) {
$args['item_id'] = $item['postid'];
$args['type'] = 'wpforo_post';
}
if( wpfval( $args, 'item_id' ) && wpfval( $args, 'type' ) ) wpforo_activity_delete( $args );
}
function wpforo_activity_content_on_post_status_change( $post, $status = 0 ) {
if( ! empty( $post ) ) {
$post['status'] = $status;
$post['posturl'] = WPF()->post->get_url( $post['postid'] );
if( ! (int) wpfval( $post, 'is_first_post' ) ) {
if( $status ) {
wpforo_activity_content_delete( $post );
} else {
wpforo_activity_content( $post );
}
}
}
}
add_action( 'wpforo_post_status_update', 'wpforo_activity_content_on_post_status_change', 9, 2 );
function wpforo_activity_content_on_topic_status_change( $topic, $status = 0 ) {
if( ! empty( $topic ) ) {
$topic['status'] = $status;
$topic['topicurl'] = WPF()->topic->get_url( $topic['topicid'] );
if( $status ) {
wpforo_activity_content_delete( $topic );
} else {
wpforo_activity_content( $topic );
}
}
}
add_action( 'wpforo_topic_status_update', 'wpforo_activity_content_on_topic_status_change', 9, 2 );
function wpforo_activity_like( $item = [] ) {
$args = [];
if( empty( $item ) ) return;
if( ( isset( $item['status'] ) && $item['status'] ) || ( isset( $item['private'] ) && $item['private'] ) ) return;
if( isset( $item['forumid'] ) && $item['forumid'] ) {
$private_for_usergroups = [ 3, 4, 5 ];
$private_for_usergroups = apply_filters( 'wpforo_activity_private_for_usergroups', $private_for_usergroups );
if( ! empty( $private_for_usergroups ) && WPF()->forum->private_forum(
$item['forumid'],
$private_for_usergroups
) ) {
return;
}
}
if( isset( $item['postid'] ) && $item['postid'] ) $args['item_id'] = $item['postid'];
$args['user_id'] = WPF()->current_userid;
$args['type'] = 'wpforo_like';
$item = wpforo_post( $item['postid'] );
if( isset( $item['url'] ) && $item['url'] ) $args['primary_link'] = $item['url'];
if( isset( $item['title'] ) ) $args['title'] = preg_replace( '|^.+?:\s*|is', '', (string) $item['title'] );
if( $args['title'] ) $args['title'] = ' "' . esc_html( $args['title'] ) . '"';
$args['action'] = sprintf( wpforo_phrase( '%s liked forum post %s', false ), '', '' );
wpforo_activity( $args );
}
function wpforo_activity_like_delete( $item = [] ) {
$args = [];
if( empty( $item ) ) return false;
if( isset( $item['postid'] ) && $item['postid'] ) {
$args['item_id'] = $item['postid'];
$args['type'] = 'wpforo_like';
}
if( $args['item_id'] && $args['type'] ) wpforo_activity_delete( $args );
}
add_action( 'wpforo_after_add_topic', 'wpforo_activity_content', 9 );
add_action( 'wpforo_after_add_post', 'wpforo_activity_content', 9 );
add_action( 'wpforo_like', 'wpforo_activity_like', 9 );
add_action( 'wpforo_after_delete_post', 'wpforo_activity_content_delete', 9 );
add_action( 'wpforo_after_delete_post', 'wpforo_activity_like_delete', 9 );
function wpforo_user_field( $field = '', $userid = 0, $echo = true ) {
$userid = ( ! $userid ) ? WPF()->current_userid : $userid;
if( ! $field || ! $userid ) return false;
$field = wpforo_member( $userid, $field );
$field = apply_filters( 'wpforo_user_field', $field, $userid );
if( ! is_array( $field ) && $field ) {
if( $echo ) {
echo $field;
} else {
return $field;
}
}
}
/**
* @param array $post
* @param bool $echo
*
* @return string|void
*/
function wpforo_content( $post, $echo = true ) {
$content = '';
if( is_array( $post ) && isset( $post['body'] ) ) {
$content = apply_filters( 'wpforo_content_before', $post['body'], $post );
$content = wpforo_kses( $content, 'post' );
$content = apply_filters( 'wpforo_content', $content, $post );
$content = wpforo_content_filter( $content, $post );
$content = apply_filters( 'wpforo_content_after', $content, $post );
$content .= ' ';
}
if( ! $echo ) return $content;
echo $content;
}
function wpforo_share_toggle( $url = '', $text = '', $location = 'side', $custom = false ) {
$position = in_array( wpforo_setting( 'social', 'sb_location_toggle' ), [ 'left', 'right' ] ) ? 'side' : wpforo_setting( 'social', 'sb_location_toggle' );
if( ! wpforo_setting( 'social', 'sb_toggle_on' ) || ( $position !== $location && ! $custom ) ) return;
$location_class = $custom ? $location : wpforo_setting( 'social', 'sb_location_toggle' );
?>
api->share_toggle( $url, $text ); ?>
api->share_buttons( $url ); ?>
tools_misc['admin_note_pages'];
$usergroups = WPF()->tools_misc['admin_note_groups'];
if( ! wpfval( WPF()->tools_misc, 'admin_note_pages' ) ) return false;
if( ! wpfval( WPF()->tools_misc, 'admin_note_groups' ) ) return false;
if( ! empty( $usergroups ) ) {
$found = array_filter( $usergroups, function( $groupid ) {
return in_array( $groupid, WPF()->current_user_groupids );
} );
if( ! empty( $found ) ) {
if( wpfval( WPF()->current_object, 'template' ) && in_array(
WPF()->current_object['template'],
$templates
) ) {
$display = true;
} else {
$display = false;
}
}
}
if( $display ) {
$note = wpforo_kses( wpforo_unslashe( trim( (string) WPF()->tools_misc['admin_note'] ) ) );
$note = apply_filters( 'wpforo_admin_note', $note );
if( $note ) {
?>
tpl->icon( 'topic', $topic, false ) ) {
$icon = WPF()->tpl->icon_base( $topic['posts'] );
$icon = implode( ' ', $icon );
}
$html = sprintf( $wrap, ' ' );
} else {
if( ( $type == 'all' || $type == 'base' ) && wpfkey( $topic, 'posts' ) ) {
$icon = WPF()->tpl->icon_base( $topic['posts'] );
$icon = implode( ' ', $icon );
$html .= sprintf( $wrap, ' ' );
}
if( $type == 'all' || $type == 'status' ) {
$icon = WPF()->tpl->icon_status( $topic );
if( ! empty( $icon ) ) {
$html = '';
foreach( $icon as $i ) {
if( ! $color ) $i['color'] = '';
$classes = $i['class'] . ' ' . $i['color'];
$html .= sprintf(
$wrap,
' '
);
}
}
}
}
if( $echo ) echo $html; else return $html;
}
function wpforo_topic_icons( $topic, $type = 'all' ) {
$icon = [];
if( wpforo_is_id( $topic ) ) $topic = wpforo_topic( $topic );
if( $type == 'mixed' ) {
$icon = WPF()->tpl->icon( 'topic', $topic, false );
} else {
if( ( $type == 'all' || $type == 'base' ) && wpfkey( $topic, 'posts' ) ) {
$icon_base = WPF()->tpl->icon_base( $topic['posts'] );
if( ! empty( $icon_base ) && is_array( $icon_base ) ) $icon = [ 'base' => $icon_base ];
}
if( $type == 'all' || $type == 'status' ) {
$icon_status = WPF()->tpl->icon_status( $topic );
if( ! empty( $icon_status ) && is_array( $icon_status ) ) $icon = $icon_status;
}
$icon = array_filter( $icon );
}
return $icon;
}
function wpforo_tags( $topic, $wrap = true, $type = 'medium', $count = false ) {
if( wpforo_is_id( $topic ) && $topic > 0 ) {
$topic = wpforo_topic( $topic );
}
if( wpfval( $topic, 'tags' ) ) {
$tags = WPF()->topic->sanitize_tags( $topic['tags'], true );
if( ! empty( $tags ) ) {
if( $wrap ) {
?>
topic->sanitize_tags( $topic['tags'], true );
if( ! empty( $tags ) ) {
foreach( $tags as $tag ) {
if( $tag ) $wheres[] = "FIND_IN_SET('" . esc_sql( $tag ) . "', tags)";
}
if( $wheres ) $args['where'] = '(' . implode( ' OR ', $wheres ) . ')';
$args['order'] = 'DESC';
$args['row_count'] = 5;
$args['orderby'] = 'modified';
$args['forumid'] = apply_filters( 'wpforo_related_topics_by_forums', $topic['forumid'] );
$args['exclude'] = [ $topic['topicid'] ];
$args = apply_filters( 'wpforo_related_topics_args', $args );
$topics = WPF()->topic->get_topics( $args );
if( ! empty( $topics ) ) {
$html .= ' ' . wpforo_phrase(
'Related Topics',
false
) . '
';
echo '' . $html . '
';
} else {
echo '
';
}
}
}
}
}
function wpforo_topic_navi( $topic ) {
if( ! empty( $topic ) ) {
if( wpfval( $topic, 'topicid' ) && wpfval( $topic, 'forumid' ) ) {
$prev_html = '';
$next_html = '';
$navi_topics = WPF()->db->get_col(
"SELECT `topicid` FROM `" . WPF()->tables->topics . "` WHERE ( `topicid` = IFNULL((SELECT min(`topicid`) FROM `" . WPF()->tables->topics . "` WHERE `topicid` > " . intval(
$topic['topicid']
) . " AND `forumid` = " . intval(
$topic['forumid']
) . " AND `status` = 0 AND `private` = 0),0) OR `topicid` = IFNULL((SELECT max(`topicid`) FROM `" . WPF()->tables->topics . "` WHERE `topicid` < " . intval(
$topic['topicid']
) . " AND `forumid` = " . intval(
$topic['forumid']
) . " AND `status` = 0 AND `private` = 0),0) ) "
);
$forum_urls = [];
$forums = array_filter( WPF()->forum->get_forums(), function( $forum ) {
return WPF()->perm->forum_can( 'vf', $forum['forumid'] );
} );
if( ! empty( $forums ) ) {
foreach( $forums as $forum ) {
$forum_urls[ 'forum_' . $forum['forumid'] ] = wpforo_home_url(
$forum['slug']
);
}
}
?>
forum->tree( 'select_box', false, $topic['forumid'], true ); ?>
' . wpforo_phrase(
'Previous Topic',
false
) . '';
}
}
if( $next ) {
$next_data = wpforo_topic( $next );
if( ! empty( $next_data ) ) {
$next_html = '
' . wpforo_phrase(
'Next Topic',
false
) . ' ';
}
}
?>
log->visitors( $topic );
if( ! empty( $visitors ) ) {
if( wpfval( $visitors, 'users' ) ) {
if( wpfval( $visitors, 'users', 'viewing' ) && wpforo_setting(
'logging',
'display_topic_current_viewers'
) ) {
$count = count( $visitors['users']['viewing'] );
if( $count ) {
if( $count > 1 ) {
$users = wpforo_phrase( '%d users ( %s )', false );
} elseif( $count == 1 ) {
$users = wpforo_phrase( '%d user ( %s )', false );
}
$user_html = [];
foreach( $visitors['users']['viewing'] as $user ) {
if( wpfval( $user, 'userid' ) ) {
$member = wpforo_member( $user['userid'] );
if( wpfval( $member, 'display_name' ) ) {
$user_html[] = wpforo_member_link(
$member,
'',
30,
'wpf-topic-visitor-link',
false
);
}
}
}
$user_html = implode( ', ', $user_html );
$users = sprintf( $users, $count, $user_html );
}
$users = apply_filters( 'wpforo_topic_viewing_users', $users, $visitors['users']['viewing'] );
}
if( wpfval( $visitors, 'users', 'viewed' ) && wpforo_setting( 'logging', 'display_recent_viewers' ) ) {
$users_visited = wpforo_phrase( 'Recently viewed by users: %s.', false );
$track_users_link = [];
foreach( $visitors['users']['viewed'] as $user ) {
if( wpfval( $user, 'userid' ) ) {
$member = wpforo_member( $user['userid'] );
if( wpfval( $member, 'display_name' ) ) {
$track_users_link[] = wpforo_member_link(
$member,
'',
30,
'wpf-topic-visitor-link',
false
) . ' ' . wpforo_date( $user['time'], 'ago', false );
}
}
}
$track_users_link = implode( ', ', $track_users_link );
$users_visited = sprintf( $users_visited, $track_users_link );
$users_visited = ' ' . $users_visited . '
';
$users_visited = apply_filters(
'wpforo_topic_viewed_users',
$users_visited,
$visitors['users']['viewed']
);
}
}
if( wpfval( $visitors, 'guests' ) && wpforo_setting( 'logging', 'display_topic_current_viewers' ) ) {
$count = count( $visitors['guests'] );
if( $count > 1 ) {
$guests = sprintf( wpforo_phrase( '%s guests', false ), $count );
} elseif( $count == 1 ) {
$guests = sprintf( wpforo_phrase( '%s guest', false ), $count );
}
}
if( $users || $guests ) {
$and = ( $users && $guests ) ? wpforo_phrase( 'and', false, 'lower' ) : '';
$html .= ' ' . sprintf(
wpforo_phrase( 'Currently viewing this topic %s %s %s.', false ),
$users,
$and,
$guests
) . '
';
}
$html .= $users_visited;
$html = apply_filters( 'wpforo_topic_visitors_info', $html, $visitors );
}
echo $html;
}
}
function wpforo_viewing( $item, $echo = true ) {
if( ! empty( $item ) && wpforo_setting( 'logging', 'display_forum_current_viewers' ) ) {
$phrase = wpforo_phrase( '(%d viewing)', false, 'lower' );
$visitors = WPF()->log->visitors( $item );
$users = ( wpfval( $visitors, 'users', 'viewing' ) ) ? count( $visitors['users']['viewing'] ) : 0;
$guests = ( wpfval( $visitors, 'guests' ) ) ? count( $visitors['guests'] ) : 0;
$viewing = (int) $users + (int) $guests;
if( $viewing > 0 ) {
$phrase = '' . sprintf( $phrase, $viewing ) . ' ';
if( $echo ) {
echo $phrase;
} else {
return $phrase;
}
}
}
}
function wpforo_topic_footer() {
if( wpfval( WPF()->current_object, 'topic' ) && wpfval( WPF()->current_object, 'template' ) && WPF()->current_object['template'] == 'post' ) {
$topic = WPF()->current_object['topic'];
?>
3 ) ? ' style="flex-wrap: wrap;"' : '';
if( ! empty( $thread['icons'] ) ) {
$i = 0;
foreach( $thread['icons'] as $icon ) {
$thread['icons_html'] .= ' ';
if( $i === 0 ) {
$thread['status_html'] .= ' ';
} else {
$thread['status_html'] .= ' ';
}
$i ++;
}
}
if( ! empty( $thread['user'] ) || ! empty( $thread['last_user'] ) ) {
$thread['usergroup_can_va'] = WPF()->usergroup->can( 'va' );
$thread['feature_avatars'] = wpforo_setting( 'profiles', 'avatars' );
$thread['users_html'] .= '';
if( $thread['usergroup_can_va'] && $thread['feature_avatars'] ) {
if( ! empty( $thread['user'] ) ) {
$thread['user_avatar'] = wpforo_user_avatar( $thread['user'], 40 );
$thread['users_html'] .= '
';
}
if( $thread['replies'] && ! empty( $thread['last_user'] ) ) {
$thread['last_user_avatar'] = wpforo_user_avatar( $thread['last_user'], 24 );
$thread['users_html'] .= '
';
}
} else {
$thread['users_html'] .= wpforo_member_link( $thread['user'], 'by', 9, '', false );
}
$thread['users_html'] .= '
';
$thread['author_html'] = '';
if( $thread['usergroup_can_va'] && $thread['feature_avatars'] ) {
if( ! empty( $thread['user'] ) ) {
$thread['user_avatar'] = wpforo_user_avatar( $thread['user'], 40 );
$thread['author_html'] .= '
' . $thread['user_avatar'] . ' ';
}
} else {
$thread['author_html'] .= wpforo_member_link( $thread['user'], 'by', 9, '', false );
}
if( $thread['usergroup_can_va'] && $thread['feature_avatars'] ) {
if( $thread['replies'] && ! empty( $thread['last_user'] ) ) {
$thread['last_user_avatar'] = wpforo_user_avatar( $thread['last_user'], 40 );
$thread['reply_html'] = '
' . $thread['last_user_avatar'] . ' ';
} else {
$thread['user_avatar'] = wpforo_user_avatar( $thread['user'], 40 );
$thread['reply_html'] = '
' . $thread['user_avatar'] . ' ';
}
}
$thread['author_html'] .= '
';
}
return $thread;
}
/**
* @param string $type
* @param array $buttons
* @param array $forum
* @param array $topic
* @param array $post
* @param bool $echo
*
* @return string
*/
function wpforo_post_buttons( $type = 'icon-text', $buttons = [], $forum = [], $topic = [], $post = [], $echo = true ) {
$buttons = WPF()->tpl->buttons( $buttons, $forum, $topic, $post, false );
if( $type === 'icon' ) {
$buttons = preg_replace( '#[\r\n\t\s\0]*]*>.*? #isu', '', (string) $buttons );
} elseif( $type === 'text' ) {
$buttons = preg_replace( '#]*>[\r\n\t\s\0]* [\r\n\t\s\0]*#isu', '', (string) $buttons );
$buttons = preg_replace( '#\swpf-tooltip=[\'\"][^\'\"]+?[\'\"]#isu', '', (string) $buttons );
} else {
$buttons = preg_replace( '#\swpf-tooltip=[\'\"][^\'\"]+?[\'\"]#isu', '', (string) $buttons );
}
if( $echo ) echo $buttons;
return $buttons;
}
function wpforo_thread_breadcrumb( $post = [], $parents = [] ) {
$html = '';
$gab = false;
if( wpfval( $post, 'parentid' ) ) {
$html .= ' ';
$parent = wpforo_post( $post['parentid'] );
$member = wpforo_member( $parent );
$parent_url = ( wpfval( $parent, 'url' ) ) ? $parent['url'] : '#post-' . $parent['parentid'];
$avatar = ( wpforo_setting( 'profiles', 'avatars' ) ) ? wpforo_user_avatar( $member, 18 ) : ' ';
$member_name = ( wpfval( $member, 'display_name' ) ) ? $member['display_name'] : wpforo_phrase(
'Guest',
false
);
$html .= '';
if( wpfval( $parents, $post['parentid'] ) ) {
$topic = wpforo_topic( $post['topicid'] );
$limit = apply_filters( 'wpforo_thread_breadcrumb_limit', 3 );
$items = array_reverse( $parents[ $post['parentid'] ] );
$last = key( array_slice( $items, - 1, 1, true ) );
foreach( $items as $key => $parentid ) {
if( $key < $limit || $key == $last ) {
$parent = wpforo_post( $parentid );
$starter = ( $topic['userid'] == $parent['userid'] ) ? true : false;
$class = ( $starter ) ? ' wpf-starter' : '';
if( ! empty( $parent ) ) {
$member = wpforo_member( $parent );
$name = ( wpfval( $member, 'display_name' ) ) ? $member['display_name'] : '';
$tooltip = ( $starter ) ? ' wpf-tooltip="' . esc_attr(
wpforo_phrase( 'Topic Author', false ) . ' - ' . $name
) . '" wpf-tooltip-size="medium"' : ' wpf-tooltip="' . esc_attr(
wpforo_phrase( 'Reply by', false ) . ' ' . $name
) . '" wpf-tooltip-size="medium"';
$parent_url = ( wpfval( $parent, 'url' ) ) ? $parent['url'] : '#post-' . $parent['parentid'];
$avatar = ( wpforo_setting( 'profiles', 'avatars' ) ) ? wpforo_user_avatar(
$member,
18
) : ' ' . $name;
if( ! $gab ) $html .= ' ';
$html .= '';
}
} else {
if( ! $gab ) $html .= ' ';
$gab = true;
}
}
}
}
echo $html;
}
function wpforo_check_threads( $posts = [] ) {
$post = array_shift( $posts );
if( wpfkey( $post, 'root' ) ) {
if( is_null( $post['root'] ) && wpfval( $post, 'topicid' ) ) {
WPF()->topic->rebuild_threads( $post['topicid'] );
wpforo_clean_cache( 'topic', $post['topicid'] );
}
}
}
function wpforo_posts_ordering_dropdown( $orderby = null, $topicid = null ) {
WPF()->tpl->posts_ordering_dropdown( $orderby, $topicid );
}
function wpforo_template_pagenavi( $class = '', $permalink = true, $paged = null, $items_count = null, $items_per_page = null ) {
WPF()->tpl->pagenavi( $paged, $items_count, $items_per_page, $permalink, $class );
}
function wpforo_tags_sort() {
if( ! wpforo_is_module_enabled( 'tags' ) ) return;
$active = wpfval( WPF()->current_object, 'tag_sort' ) ?: 'count';
$base_url = wpforo_home_url( wpforo_settings_get_slug( 'tags' ) );
// Inline stroke SVG icons. Layout lives in theme style.css, colors in styles/matrix.css. Static, trusted markup.
$icons = [
'count' => ' ',
'az' => ' ',
'za' => ' ',
];
$labels = [ 'count' => 'Frequency', 'az' => 'A-Z', 'za' => 'Z-A' ];
?>
tpl->add_topic_button( $forumid );
}
function wpforo_feed_rss2_url( $echo = true, $general = false ) {
WPF()->feed->rss2_url( $echo, $general );
}
function wpforo_feed_link( $type = 'topic' ) {
$nofollow = apply_filters( 'wpforo_feed_link_nofollow', false );
$nofollow = ( $nofollow ) ? ' rel="nofollow" ' : '';
if( wpforo_is_module_enabled( 'rss' ) && wpforo_setting( 'rss', 'feed' ) ): ?>
title="" target="_blank" class="wpf-button-outlined">
RSS
title="" target="_blank" class="wpf-button-outlined">
|
title="" target="_blank">
|
title="" target="_blank">
tpl->topic_form_forums_selectbox( $forumid );
}
function wpforo_notifications() {
WPF()->activity->notifications();
}
function wpforo_unread_url( $topicid = 0, $url = '', $echo = true, $force = false ) {
//Only for loggedin users
$enabled = ( ! $force ? wpforo_setting( 'logging', 'goto_unread' ) : true );
if( WPF()->current_userid && $enabled && $topicid && $url ) {
//Get read topics
$topics = WPF()->log->get_read_topics();
if( $last_read_id = wpfval( $topics, $topicid ) ) {
//Make sure the post still located in current topic. When admin split a topic
//and move the last reply to other topic, the users unread topic array isn't updated,
//It's not reasonable to update usermeta of each user, so it's better to check
//the post topic ID here. if the reply is split and moved to other topic use the
//topic last post id.
$last_read_post = wpforo_post( $last_read_id );
if( $topicid == wpfval( $last_read_post, 'topicid' ) ) {
$first_unread_id = 0;
$jump_to_first_unread = apply_filters( 'wpforo_jump_to_first_unread', true );
if( $jump_to_first_unread ) {
//Get first unread postid
$first_unread_id = WPF()->post->next_post( $last_read_id, $topicid );
}
//Decide to whether execute more SQLs and create direct URLs or not
$direct_url = apply_filters( 'wpforo_build_direct_unread_post_url', false );
//Create new URLs
if( $first_unread_id ) {
//Change URL to first unread post
if( $direct_url ) {
$url = wpforo_post( $first_unread_id, 'url' );
} else {
$url = ( strpos( (string) $url, '#' ) !== false ) ? preg_replace(
'|#.+$|',
'#post-' . intval( $first_unread_id ),
(string) $url
) : $url . '#post-' . intval( $first_unread_id );
}
} else {
//Change URL to last read post
if( $direct_url ) {
$url = wpforo_post( $last_read_id, 'url' );
} else {
$url = ( strpos( (string) $url, '#' ) !== false ) ? preg_replace(
'|#.+$|',
'#post-' . intval( $last_read_id ),
(string) $url
) : $url . '#post-' . intval( $last_read_id );
}
}
} elseif( $last_postid = wpforo_topic( $topicid, 'last_post' ) ) {
$url = wpforo_post( $last_postid, 'url' );
}
}
} else {
$direct_topic_url = apply_filters( 'wpforo_direct_topic_url', true );
if( $direct_topic_url ) {
$url = preg_replace( '|#post-\d+|i', '', (string) $url );
$url = WPF()->strip_url_paged_var( $url );
}
}
if( ! $echo ) return esc_url( (string) $url );
echo esc_url( (string) $url );
}
function wpforo_unread_button( $topicid = 0, $url = '', $echo = true, $postid = 0 ) {
$button = '';
if( ! $postid && $topicid && $url && WPF()->current_userid && wpforo_setting( 'logging', 'goto_unread_button' ) ) {
$unread = wpforo_unread( $topicid, 'topic', false );
if( $unread ) {
$button_link = apply_filters( 'wpforo_jump_to_unread_button_link', false );
$button_text = str_replace( [ '{', '}' ], '', wpforo_phrase( '{new}', false ) );
if( wpforo_setting( 'logging', 'goto_unread' ) ) {
if( $button_link ) {
$url = wpforo_unread_url( $topicid, $url, false, true );
}
} else {
$url = wpforo_unread_url( $topicid, $url, false, true );
$button_link = true;
}
$button = ( $button_link ) ? '' . $button_text . ' ' : '' . $button_text . ' ';
}
} elseif( $postid && $topicid && WPF()->current_userid ) {
$unread = wpforo_unread( $topicid, 'post', false, $postid );
if( $unread ) {
$button_text = str_replace( [ '{', '}' ], '', wpforo_phrase( '{new}', false ) );
$button = '' . $button_text . ' ';
}
}
if( ! $echo ) return $button;
echo $button;
}
/**
* @param array|string $forum
* @param string $before
* @param string $after
* @param bool $echo
*
* @return string
*/
function wpforo_forum_title( $forum, $before = '', $after = '', $echo = true ) {
$title = is_array( $forum ) ? (string) wpfval( $forum, 'title' ) : $forum;
$title = esc_html( $title );
$title = apply_filters( 'wpforo_forum_title', $title, $forum );
if( $title ) $title = $before . $title . $after;
if( $echo ) echo $title;
return $title;
}
/**
* @param array|string $forum
* @param string $before
* @param string $after
* @param bool $echo
*
* @return string
*/
function wpforo_forum_description( $forum, $before = '', $after = '', $echo = true ) {
$description = is_array( $forum ) ? (string) wpfval( $forum, 'description' ) : $forum;
$description = apply_filters( 'wpforo_forum_description', $description, $forum );
$description = trim( $description );
if( $description ) $description = $before . $description . $after;
if( $echo ) echo $description;
return $description;
}
function wpforo_admin_cpanel() {
if( WPF()->current_object['template'] === 'forum' && wpforo_setting(
'components',
'admin_cp'
) && wpforo_current_user_is( 'admin' ) ) {
$toggle = get_user_meta( WPF()->current_userid, 'wpf-acp-toggle', true );
if( ! $toggle || $toggle === 'open' ) {
$display = 'block';
$title = wpforo_phrase( 'Close', false );
$icon = ' ';
} else {
$display = 'none';
$title = wpforo_phrase( 'Open', false );
$icon = ' ';
}
?>
tpl->member_template();
}
/**
* show member menu
*/
function wpforo_member_tabs() {
WPF()->tpl->member_menu();
}
/**
* get current object user or empty array
*
* @return array
*/
function wpforo_get_current_object_user() {
return WPF()->current_object['user'];
}
/**
* @param array|string $template
*
* @return bool
*/
function wpforo_is_member_template( $template = null ) {
if( $template = WPF()->tpl->get_template( $template ) ) {
return wpfkey(
WPF()->tpl->member_templates,
$template['key']
);
}
return false;
}
/**
* show wpforo template
*
* @param array|string $template
*/
function wpforo_template( $template = null ) {
$template = apply_filters( 'wpforo_template', $template );
if( ! $template ) $template = WPF()->current_object['template'] ? WPF()->current_object['template'] : '404';
if( WPF()->tpl->can_view_template( $template, WPF()->current_object['user'] ) ) {
if( $path = WPF()->tpl->get_template_path( $template ) ) {
if( file_exists( $path ) ) include( $path );
} else {
WPF()->tpl->show_template( $template );
}
} else {
WPF()->tpl->show_msg( wpforo_phrase( 'You do not have permission to view this page', false ) );
}
}
/**
* @param string $html
*
* @return string
*/
function wpforo_apply_ucf_shortcode( $html ) {
return preg_replace_callback( '#\[wpfucf\s([^\[\]]+?)]#iu', function( $shortcode ) {
if( preg_match( '#(?:^|\s)field=[\'\"]([^\'\"]+?)[\'\"]#iu', $shortcode[1], $field ) ) {
if( $field_key = trim( $field[1] ) ) {
$userid = 0;
if( preg_match(
'#(?:^|\s)id=[\'\"]([^\'\"]+?)[\'\"]#iu',
$shortcode[1],
$id
) ) {
$userid = wpforo_bigintval( $id[1] );
}
if( ! $userid ) {
$userid = WPF()->current_object['userid'] ? WPF()->current_object['userid'] : WPF()->current_userid;
}
if( $f = WPF()->member->get_field( $field_key ) ) {
if( wpfval( $f, 'type' ) === 'html' && ( $html = trim( (string) wpfval( $f, 'html' ) ) ) ) {
return (string) WPF()->form->field_html( $f );
} elseif( WPF()->form->can_view( $f ) && WPF()->form->can_show_value( $f ) ) {
$f['value'] = wpforo_member( $userid, $field_key );
$f = WPF()->form->prepare_values( WPF()->form->esc_field( $f ), $userid );
return $f['value'];
}
}
}
}
return ''; // if that field has not found
}, (string) $html );
}
/**
* @param array|string $template
* @param array|int $member
* @param string $default
*
* @return string
*/
function wpforo_member_url( $template = null, $member = null, $default = '' ) {
$member_url = $default;
$template = WPF()->tpl->get_template( $template );
if( $template && wpforo_is_member_template( $template ) ) {
if( ! $member ) $member = WPF()->current_object['user'] ? WPF()->current_object['user'] : WPF()->current_user;
$profile_url = WPF()->member->get_profile_url( $member, $template['key'] );
if( $profile_url ) $member_url = $profile_url;
}
return $member_url;
}
function wpforo_mark_all_read_link() {
if( ! wpforo_is_bot() ) : ?>
tpl->post_search_form( $values );
}
function wpforo_member_search_form() {
WPF()->tpl->member_search_form();
}
function wpforo_member_buttons( $member ) {
WPF()->tpl->member_buttons( $member );
}
function wpforo_sanitize_search_body( $body, $needle, $post = [] ) {
$body = wpforo_content_filter( $body, $post );
$body = wpforo_text( $body, 0, false );
$words = explode( ' ', trim( (string) $needle ) );
if( ! empty( $words ) ) {
$body_len = apply_filters( 'wpforo_search_results_body_length', 564 );
$pos = mb_stripos( $body, " " . trim( $words[0] ), 0, get_option( 'blog_charset' ) );
if( strlen( (string) $body ) > $body_len && $pos !== false ) {
if( $pos > ( $body_len / 2 ) ) {
$bef_body = "... ";
$start = mb_stripos( $body, " ", ( $body_len / 2 ), get_option( 'blog_charset' ) );
} else {
$bef_body = "";
$start = 0;
}
if( ( mb_strlen( (string) $body, get_option( 'blog_charset' ) ) - $start ) > $body_len ) {
$aft_body = " ...";
} else {
$aft_body = "";
}
$body = $bef_body . mb_substr(
(string) $body,
$start,
$body_len,
get_option( 'blog_charset' )
) . $aft_body;
}
foreach( $words as $word ) {
$word = trim( (string) $word );
$body = preg_replace(
'#(?:^|\s+)' . preg_quote( esc_html( $word ) ) . '#iu',
' ' . esc_html( $word ) . ' ',
(string) $body
);
}
}
return $body;
}
function wpforo_topic_starter( $topic, $post, $type = 'full' ) {
$starter = false;
$topic_user = (int) wpfval( $topic, 'userid' );
$post_user = (int) wpfval( $post, 'userid' );
$topic_guest = wpfval( $topic, 'email' );
$post_guest = wpfval( $post, 'email' );
if( $topic_user && $topic_user === $post_user ) {
$starter = true;
} elseif( $topic_guest && $topic_guest === $post_guest ) {
$starter = true;
}
if( $starter ) {
if( $type === 'full' ) {
echo ' ' . wpforo_phrase(
'Topic starter',
false
) . ' ';
} elseif( $type === 'icon' ) {
echo ' ';
} elseif( $type === 'label' ) {
echo '' . wpforo_phrase( 'Topic starter', false ) . ' ';
}
}
}
function wpforo_get_not_replied_topicids() {
$sql = "SELECT `topicid`, COUNT(DISTINCT userid) AS userid_count FROM `" . WPF()->tables->posts . "` GROUP BY `topicid` HAVING userid_count = 1";
return (array) WPF()->db->get_col( $sql, 0 );
}
/**
* @param array $topic
* @param string $url
* @param string $structure
* {i} - topic icon (empty, one reply, replied)
* {is} - topic icon and status icons (+ sticky, closed, private...)
* {t} - topic title
* {tc} - topic title cut by x number of chars
* {au} - link opening tag, link goes to first unread post
* {at} - link opening tag, link goes to the topic url
* {af} - link opening tag, link goes to the first post
* {a} - link opening tag, link goes to the provided url
* {/a} - link closing tag, this is required
* {v} - displays number of users currently viewing the topic
* {n} - displays [new] info when a new unread post has been posted in the topic
*
* Example {a}{t}{/a} - this is the topic title as a link going to the first post.
*
* @param bool $echo
* @param string $class
* @param int $length
*
*
*
*
* @return mixed|string|void|null
*/
function wpforo_topic_title( $topic, $url, $structure = '{i}{au}{t}{/a}{n}{v}', $echo = true, $class = '', $length = 70 ) {
$html = __( 'No Title', 'wpforo' );
if( $title = trim( esc_html( (string) wpfval( $topic, 'title' ) ) ) ) {
$structure = apply_filters( 'wpforo_topic_title_structure', $structure, $topic );
$class = ( $class ) ? ' class="' . esc_attr( $class ) . '"' : '';
$a = '';
$topic['url'] = $url;
// For better performance, make sure the component in demand before getting it.
$title_cut = ( strpos( (string) $structure, '{tc}' ) !== false ) ? esc_html( wpforo_text( $topic['title'], $length, false ) ) : '';
$icon_all = ( strpos( (string) $structure, '{i}' ) !== false ) ? wpforo_topic_icon( $topic, 'all', true, false ) : '';
$icon_status = ( strpos( (string) $structure, '{is}' ) !== false ) ? wpforo_topic_icon( $topic, 'status', true, false ) : '';
$viewing = ( strpos( (string) $structure, '{v}' ) !== false ) ? wpforo_viewing( $topic, false ) : '';
$new = ( strpos( (string) $structure, '{n}' ) !== false ) ? wpforo_unread_button( $topic['topicid'], $url, false ) : '';
$au = ( strpos( (string) $structure, '{au}' ) !== false ) ? ' ' : '';
$at = ( strpos( (string) $structure, '{at}' ) !== false ) ? ' ' : '';
$af = ( strpos( (string) $structure, '{af}' ) !== false ) ? ' ' : '';
$components = [
'{a}' => $a,
'{au}' => $au,
'{at}' => $at,
'{af}' => $af,
'{/a}' => ' ',
'{i}' => $icon_all,
'{is}' => $icon_status,
'{t}' => $title,
'{tc}' => $title_cut,
'{v}' => ' ' . $viewing,
'{n}' => ' ' . $new,
'{p}' => '',
'{pt}' => '',
];
$components = apply_filters( 'wpforo_topic_title_components', $components, $topic );
$html = strtr( $structure, $components );
$html = apply_filters( 'wpforo_topic_title_html', $html, $topic, $structure, $components );
}
if( ! $echo ) return $html;
echo $html;
}
function wpforo_single_title( $type = 'post', $item = [], $before = '', $after = '', $echo = true ) {
$title = '';
if( $type === 'post' && wpfval( $item, 'title' ) ) {
$icon_title = WPF()->tpl->icon( 'topic', $item, false, 'title' );
if( $icon_title ) {
$title .= '[' . esc_html( $icon_title ) . '] ';
}
$title = apply_filters( "wpforo_single_{$type}_pre_title", $title, $item );
$title .= esc_html( wpforo_text( $item['title'], 0, false ) );
}
$title = apply_filters( "wpforo_single_{$type}_title", $title );
if( $title ) $title = $before . $title . $after;
if( $echo ) echo $title;
return $title;
}
function wpforo_schema( $forum, $topic, $post, $type = '' ) {
$schema = '';
if( apply_filters( "wpforo_schema", true ) ) {
if( ! $type ) {
$type = 'DiscussionForumPosting';
if( 3 === (int) wpfval( $forum, 'layout' ) ) {
$type = 'QAPage';
}
}
if( $type === 'QAPage' && wpfval( $topic, 'topicid' ) ) {
$extended = apply_filters( "wpforo_schema_qa_extended_best_answer", true );
$best_answer = WPF()->post->get_best_answer( $topic['topicid'], $extended );
$suggested_answers_count = apply_filters( "wpforo_schema_qa_suggested_answers_count", 3 );
$suggested_answers = WPF()->post->get_suggested_answers(
$topic['topicid'],
$suggested_answers_count
);
$schema .= '
';
} elseif( wpfval( $topic, 'topicid' ) ) {
$topic_posts = '';
$paged = WPF()->current_object['paged'];
$posts = WPF()->current_object['posts'];
$topic_post = wpforo_post( $topic['first_postid'] );
if( $paged > 1 || ( $paged === 1 && count( $posts ) > 1 ) ) {
$topic_posts .= '"comment": [';
foreach( $posts as $key => $post ) {
if( $paged === 1 && $key == 0 ) continue;
$post_text = wpforo_text( stripslashes( sanitize_text_field( $post['body'] ) ), 5000, false );
$post_author = wpforo_generate_scheme_author_object( $post['userid'] );
$post_images = wpforo_generate_scheme_image_object( $post['body'] );
if( ! $post_text && ! $post_images ) continue;
$topic_posts .= '{
"@type": "Comment",
"text": "' . esc_attr( $post_text ) . '",' . $post_images . '
"datePublished": "' . gmdate( 'Y-m-d\TH:i:s\Z', strtotime( $post['created'] ) ) . '"' . $post_author . '
},';
}
$topic_posts = ',' . trim( $topic_posts, ',' ) . ']';
}
$topic_author = wpforo_generate_scheme_author_object( $topic['userid'] );
$topic_images = wpforo_generate_scheme_image_object( $topic_post['body'] );
$topic_text = wpforo_text( stripslashes( sanitize_text_field( $topic_post['body'] ) ), 5000, false );
if( $topic_text || $topic_images ) {
$schema .= '
';
}
}
}
return $schema;
}
function wpforo_template_profile_board_panel() {
echo WPF()->tpl->profile_board_panel();
}
function wpforo_template_profile_activity_panel() {
echo WPF()->tpl->profile_activity_panel();
}
function wpforo_template_profile_favored_panel() {
echo WPF()->tpl->profile_favored_panel();
}
function wpforo_profile_head_attrs( $user ) {
printf(
'style="background-image:url(\'%1$s\')"',
esc_url(
trim( (string) wpfval( $user, 'cover' ) ) ? trim( (string) wpfval( $user, 'cover' ) ) . '?lm=' . time() : wpforo_setting( 'profiles', 'default_cover' )
)
);
}
function wpforo_template_profile_action_buttons( $user ) {
do_action( 'wpforo_template_profile_action_buttons_left', $user ); ?>
tpl->get_member_actions_html( $user );
}
function wpforo_get_users_count_for_topic( $topicid = 0 ) {
if( ! $topicid ) $topicid = WPF()->current_object['topicid'];
return WPF()->post->get_users_count_for_topic( $topicid );
}
function wpforo_get_likes_for_topic( $topicid ) {
return WPF()->reaction->get_likes_for_topic( $topicid );
}
function wpforo_display_header( $template = '' ) {
if( ! $template ) $template = WPF()->current_object['template'];
return ! wpforo_is_member_template( $template ) || wpforo_setting( 'profiles', 'profile_header' );
}
function wpforo_display_footer( $template = '' ) {
if( ! $template ) $template = WPF()->current_object['template'];
return ( ( wpforo_is_member_template( $template ) && wpforo_setting(
'profiles',
'profile_footer'
) ) || ( ! wpforo_is_member_template( $template ) && wpforo_setting( 'components', 'footer' ) ) );
}
function wpforo_forum_list_need_add_topic_button( $forumid ) {
switch( WPF()->forum->get_layout( $forumid ) ) {
case 2:
$need_button = wpforo_setting( 'forums', 'layout_simplified_add_topic_button' );
break;
case 3:
$need_button = wpforo_setting( 'forums', 'layout_qa_add_topic_button' );
break;
case 4:
$need_button = wpforo_setting( 'forums', 'layout_threaded_add_topic_button' );
break;
default:
$need_button = true;
break;
}
return $need_button;
}
function wpforo_get_forum_cover_styles( $forum ) {
$r = [
'cover' => '',
'title' => '',
'info' => '',
'button' => '',
'blur' => '',
];
if( $forum['cover_url'] ) {
$border_radius = ( (int) $forum['layout'] !== 4 ) ? 'border-radius: 4px;' : ( ! is_rtl() ? 'border-radius: 4px 0 0 4px;' : 'border-radius: 0 4px 4px 0;' );
$r['cover'] = sprintf(
'style="background-image:url(\'%1$s\'); background-position: center; background-size: cover; height:170px; padding:0;"',
esc_attr( $forum['cover_url'] )
);
$r['blur'] = 'style="background: rgba(255, 255, 255, 0.7); color:#000"';
$r['title'] = 'style="display: inline-block; line-height: 20px; ' . $border_radius . ' color:#000"';
$r['info'] = 'style="padding-bottom: 1px; padding-top:3px;"';
$r['button'] = 'style="padding-top:3px; padding-bottom: 2px; line-height: 26px; ' . ( ! is_rtl() ? 'border-radius: 0 4px 4px 0;' : 'border-radius: 4px 0 0 4px;' ) . '"';
}
return $r;
}
function wpforo_post_search_url( $field_name, $field_value ) {
return wpforo_home_url(
'?' . http_build_query(
[
'wpfs' => '',
'wpfin' => 'entire-posts',
'wpfd' => '0',
'wpfob' => 'date',
'wpfo' => 'desc',
'data' => [
'text_field' => '',
'uniqid' => '',
$field_name => $field_value,
],
]
)
);
}
function wpforo_post_search_link( $field_name, $field_value ) {
return sprintf(
'%2$s ',
wpforo_post_search_url( $field_name, $field_value ),
$field_value
);
}
function wpforo_get_sum_of_topics_posts( int $forumid, bool $check_permission = true ): array {
return WPF()->forum->get_sum_of_topics_posts( $forumid, $check_permission );
}
function _wpforo_main_wrap_classes(): array {
$classes = [];
switch( wpforo_setting( 'components', 'sidebar_location' ) ) {
case 'left':
$classes[] = 'wpforo-left-sidebar-layout';
break;
case 'right':
$classes[] = 'wpforo-right-sidebar-layout';
break;
}
return apply_filters( 'wpforo_main_wrap_classes', $classes );
}
function wpforo_main_wrap_classes(): void {
echo implode( ' ', _wpforo_main_wrap_classes() );
}
function wpforo_get_recent_page_title(): string {
$view = wpfval( WPF()->current_object['args'], 'view' );
switch( $view ) {
case 'unread':
$page_title = wpforo_phrase( 'Unread Posts', false );
break;
case 'no-replies':
$page_title = wpforo_phrase( 'Not Replied Topics', false );
break;
case 'solved':
$page_title = wpforo_phrase( 'Solved Topics', false );
break;
case 'unsolved':
$page_title = wpforo_phrase( 'Unsolved Topics', false );
break;
case 'closed':
$page_title = wpforo_phrase( 'Closed Topics', false );
break;
case 'opened':
$page_title = wpforo_phrase( 'Open Topics', false );
break;
case 'sticky':
$page_title = wpforo_phrase( 'Sticky Topics', false );
break;
case 'private':
$page_title = wpforo_phrase( 'Private Topics', false );
break;
case 'unapproved':
$page_title = wpforo_phrase( 'Unapproved Posts', false );
break;
default:
$page_title = wpforo_phrase( 'Recent Posts', false );
break;
}
return apply_filters( 'wpforo_recent_posts_page_title', $page_title, WPF()->current_object['args'], $view );
}
function wpforo_get_rss_feed_links(): string {
if( wpforo_setting( 'rss', 'feed' ) ) {
return sprintf(
' |
%3$s
|
%6$s
',
WPF()->feed->rss2_url( false, 'forum' ),
wpforo_phrase( 'Forums RSS Feed', false ),
wpforo_phrase( 'Forums', false ),
WPF()->feed->rss2_url( false, 'topic' ),
wpforo_phrase( 'Topics RSS Feed', false ),
wpforo_phrase( 'Topics', false )
);
}
return '';
}
function wpforo_rss_feed_links(): void {
echo wpforo_get_rss_feed_links();
}
function wpforo_get_recent_page_filter_selectbox(): string {
$filters = [
'recent' => wpforo_phrase( 'Recent Posts', false ),
'unread' => wpforo_phrase( 'Unread Posts', false ),
'no-replies' => wpforo_phrase( 'Not Replied Topics', false ),
'solved' => wpforo_phrase( 'Solved Topics', false ),
'unsolved' => wpforo_phrase( 'Unsolved Topics', false ),
'closed' => wpforo_phrase( 'Closed Topics', false ),
'opened' => wpforo_phrase( 'Open Topics', false ),
'sticky' => wpforo_phrase( 'Sticky Topics', false ),
];
// Add admin/moderator-specific filters
if( wpforo_current_user_is( 'admin' ) || wpforo_current_user_is( 'moderator' ) ) {
$filters['private'] = wpforo_phrase( 'Private Topics', false );
$filters['unapproved'] = wpforo_phrase( 'Unapproved Posts', false );
}
$options_html = '';
foreach( $filters as $key => $value ) {
$options_html .= sprintf(
'%4$s ',
$key !== 'recent' ? $key : '',
( wpfval( WPF()->current_object['args'], 'prefixid' ) ? sprintf( '&prefixid=%1$d', WPF()->current_object['args']['prefixid'] ) : '' ),
wpfo_check( wpfval( WPF()->current_object['args'], 'view' ), $key, 'selected', false ),
$value
);
}
return sprintf( '%1$s ', $options_html );
}
/**
* Get icon HTML for activity type
* Reads from WPF()->activity->actions for single source of truth
*
* @param string $type Activity type
* @return string Icon HTML (SVG)
*/
function wpforo_activity_icon( $type ) {
$actions = WPF()->activity->actions;
$icon = isset( $actions[ $type ]['icon'] ) ? $actions[ $type ]['icon'] : '';
if( ! $icon ) {
$icon = isset( $actions['default']['icon'] ) ? $actions['default']['icon'] : '';
}
return apply_filters( 'wpforo_activity_icon', $icon, $type );
}
/**
* Get label for activity type
*
* @param string $type Activity type
* @return string Translated label
*/
function wpforo_activity_label( $type ) {
$labels = [
'wpforo_topic' => wpforo_phrase( 'created the topic', false ),
'wpforo_post' => wpforo_phrase( 'replied to', false ),
'edit_topic' => wpforo_phrase( 'edited a topic', false ),
'edit_post' => wpforo_phrase( 'edited a post', false ),
'new_reply' => wpforo_phrase( 'replied to', false ),
'new_like' => wpforo_phrase( 'liked', false ),
'new_dislike' => wpforo_phrase( 'disliked', false ),
'new_up_vote' => wpforo_phrase( 'voted up', false ),
'new_down_vote' => wpforo_phrase( 'voted down', false ),
'new_reaction' => wpforo_phrase( 'reacted to', false ),
'new_mention' => wpforo_phrase( 'mentioned in', false ),
'new_favorite' => wpforo_phrase( 'favorited', false ),
'topic_solved' => wpforo_phrase( 'marked as solved', false ),
'new_closed' => wpforo_phrase( 'closed the topic', false ),
'default' => wpforo_phrase( 'activity', false ),
];
$labels = apply_filters( 'wpforo_activity_labels', $labels );
return wpfval( $labels, $type ) ?: $labels['default'];
}
/**
* Render detailed activity info HTML based on activity type
*
* @param array $activity Activity data
* @param array $member User who performed the activity
* @return string HTML for the activity info row
*/
function wpforo_activity_info_html( $activity, $member ) {
$type = $activity['type'];
$html = '';
// Get post and topic data if available
$post = [];
$topic = [];
$forum = [];
$post_author = [];
if( $activity['itemid'] ) {
// For wpforo_topic, topic_solved, and topic_closed, itemid is the topicid, not postid
if( $type === 'wpforo_topic' || $type === 'topic_solved' || $type === 'topic_closed' ) {
$topic = WPF()->topic->get_topic( $activity['itemid'] );
if( $topic && ! empty( $topic['forumid'] ) ) {
$forum = WPF()->forum->get_forum( $topic['forumid'] );
}
} else {
$post = WPF()->post->get_post( $activity['itemid'] );
if( $post && ! empty( $post['topicid'] ) ) {
$topic = WPF()->topic->get_topic( $post['topicid'] );
if( $topic && ! empty( $topic['forumid'] ) ) {
$forum = WPF()->forum->get_forum( $topic['forumid'] );
}
// Get post author for reaction-type activities
if( ! empty( $post['userid'] ) && $post['userid'] != $activity['userid'] ) {
$post_author = wpforo_member( $post['userid'] );
}
}
}
}
// Build topic link
$topic_title = '';
$topic_link = '';
if( $topic ) {
$topic_title = esc_html( $topic['title'] );
$topic_url = $activity['permalink'] ?: WPF()->topic->get_url( $topic['topicid'] );
$topic_link = '' . $topic_title . ' ';
}
// Build forum link
$forum_link = '';
if( $forum ) {
$forum_title = esc_html( $forum['title'] );
$forum_url = WPF()->forum->get_forum_url( $forum );
$forum_link = '' . $forum_title . ' ';
}
// Build post author link for reactions
$author_link = '';
if( $post_author && ! empty( $post_author['display_name'] ) ) {
$author_link = '' . esc_html( $post_author['display_name'] ) . ' ';
}
// Build HTML based on activity type
switch( $type ) {
case 'wpforo_topic':
// {User} created the topic {Topic Title} in {Forum Title}
$html = sprintf(
wpforo_phrase( 'created the topic %1$s in %2$s', false ),
$topic_link,
$forum_link
);
break;
case 'wpforo_post':
case 'new_reply':
// {User} replied to the topic {Topic Title}
$html = sprintf(
wpforo_phrase( 'replied to the topic %s', false ),
$topic_link
);
break;
case 'new_like':
case 'new_dislike':
case 'new_up_vote':
case 'new_down_vote':
case 'new_reaction':
// {User} reacted to {Author}'s post in the topic {Topic Title}
if( $author_link ) {
$html = sprintf(
wpforo_phrase( 'reacted to %1$s\'s post in the topic %2$s', false ),
$author_link,
$topic_link
);
} else {
$html = sprintf(
wpforo_phrase( 'reacted to a post in the topic %s', false ),
$topic_link
);
}
break;
case 'new_favorite':
// {User} favorited {Author}'s post in the topic {Topic Title}
if( $author_link ) {
$html = sprintf(
wpforo_phrase( 'favorited %1$s\'s post in the topic %2$s', false ),
$author_link,
$topic_link
);
} else {
$html = sprintf(
wpforo_phrase( 'favorited a post in the topic %s', false ),
$topic_link
);
}
break;
case 'new_solved':
case 'topic_solved':
// {User} marked as solved the topic {Topic Title}
$html = sprintf(
wpforo_phrase( 'marked as solved the topic %s', false ),
$topic_link
);
break;
case 'new_closed':
case 'topic_closed':
// {User} closed the topic {Topic Title}
$html = sprintf(
wpforo_phrase( 'closed the topic %s', false ),
$topic_link
);
break;
case 'post_answer':
// {User} marked as answer a post in the topic {Topic Title}
$html = sprintf(
wpforo_phrase( 'marked as answer a post in the topic %s', false ),
$topic_link
);
break;
case 'new_mention':
// {User} mentioned you in {Topic Title}
$html = sprintf(
wpforo_phrase( 'mentioned you in %s', false ),
$topic_link
);
break;
case 'edit_topic':
case 'edit_post':
// {User} edited a post in {Topic Title}
$html = sprintf(
wpforo_phrase( 'edited a post in %s', false ),
$topic_link
);
break;
default:
// Fallback to simple label
$label = wpforo_activity_label( $type );
$html = $label . ( $topic_link ? ' ' . $topic_link : '' );
break;
}
return apply_filters( 'wpforo_activity_info_html', $html, $activity, $member );
}