user_id ) ) {
$user = get_user_by( 'id', $comment->user_id );
} else {
$user = get_user_by( 'email', $comment->comment_author_email );
}
if ( ! $user ) {
return $avatar;
}
} elseif ( is_string( $id_or_email ) ) {
$user = get_user_by( 'email', $id_or_email );
} else {
return $avatar;
}
if ( ! $user ) {
return $avatar;
}
$user_id = $user->ID;
$profile_image_url = get_the_author_meta( 'blogsy_author_profile_image', $user_id );
if ( $profile_image_url ) {
return '
';
}
return $avatar;
}
add_filter( 'pre_get_avatar', 'blogsy_replace_author_avatar', 10, 3 );
/**
* Add class to body tag
*
* Hook: 'body_class'
*
* @param array $classes Classes for the body element.
* @return array $classes Modified classes for the body element.
* @since 1.0.0
*/
function blogsy_body_class( array $classes ): array {
global $post;
// Menu accessibility support.
$classes[] = 'blogsy-menu-accessibility';
if ( Helper::get_option( 'smooth_scroll' ) ) {
$classes[] = 'blogsy-smooth-scroll';
}
// Button shape style.
$classes[] = 'pt-shape--' . sanitize_html_class( Helper::get_option( 'button_shape_style' ) );
// Header related styles.
if ( blogsy_is_header_displayed() ) {
// Header layout.
$classes[] = 'pt-header-' . sanitize_html_class( Helper::get_option( 'header_layout' ) );
}
// Disable page card style.
if ( ( get_post_meta( $post->ID, 'blogsy_disable_page_card_style', true ) ) ) {
$classes[] = 'blogsy-disable-page-card-style';
}
return $classes;
}
add_filter( 'body_class', 'blogsy_body_class' );
/**
* Add Theme Scheme to HTML tag
*
* Hook: 'language_attributes'
*
* @param string $output Language attributes output.
* @return string $output Modified language attributes output.
* @since 1.0.0
*/
function blogsy_theme_scheme( string $output ): string {
if ( blogsy_dark_mode_enabled() ) {
$output .= ' scheme="' . blogsy_current_theme_scheme() . '"';
if ( Helper::get_option( 'always_dark_mode' ) ) {
$output .= ' dark-theme=""';
}
}
return $output;
}
add_filter( 'language_attributes', 'blogsy_theme_scheme' );
/**
* Full Size for Gif image thumbnail
*
* Hook: 'wp_get_attachment_image_src
*
* @param array $image Image data.
* @param int $attachment_id Attachment ID.
* @param string|array $size Size of image.
* @param bool $icon Whether the image is an icon.
* @return array $image Image data.
* @since 1.0.0
*/
function blogsy_full_size_gif_images( $image, $attachment_id, $size, bool $icon ) {
if ( ! $image ) {
// No image found, return early.
return $image;
}
if ( \Blogsy\Helper::get_option( 'full_size_gif' ) && ! empty( $image[0] ) ) {
$format = wp_check_filetype( $image[0] );
if ( ! empty( $format ) && 'gif' === $format['ext'] ) {
// Only do replacement if $size is a string and not 'full'.
if ( is_string( $size ) && 'full' !== $size ) {
return wp_get_attachment_image_src( $attachment_id, 'full', $icon );
}
}
}
return $image;
}
add_filter( 'wp_get_attachment_image_src', 'blogsy_full_size_gif_images', 10, 4 );
/**
* Limit search for custom post types
*
* Hook: 'pre_get_posts'
*
* @param WP_Query $query The WP_Query instance (passed by reference).
* @since 1.0.0
*/
function blogsy_limit_search_post_types( WP_Query $query ): WP_Query {
$post_types = Helper::get_option( 'search_post_types' );
if ( is_array( $post_types ) && count( $post_types ) && $query->is_search && $query->is_main_query() && ! is_admin() ) {
$query->set( 'post_type', $post_types );
}
return $query;
}
add_filter( 'pre_get_posts', 'blogsy_limit_search_post_types', 100 );
/**
* Filters the arguments for a single nav menu item to include dropdown indicators.
*
* Hook: 'nav_menu_item_args
*
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param WP_Post $item Menu item data object.
* @since 1.0.0
*/
function blogsy_nav_menu_item_args( stdClass $args, WP_Post $item ): stdClass {
$dropdown_indicator = \Blogsy\Icon::get_svg( 'chevron-down', 'ui', [ 'size' => 17 ] );
if ( in_array( 'menu-item-has-children', $item->classes, true ) ) {
if ( false === strpos( $args->link_after, $dropdown_indicator ) ) {
$args->link_after .= $dropdown_indicator;
$args->after = '';
}
} else {
$args->link_after = str_replace( $dropdown_indicator, '', $args->link_after );
$args->after = '';
}
return $args;
}
add_filter( 'nav_menu_item_args', 'blogsy_nav_menu_item_args', 10, 3 );
/**
* Filters the arguments for a single nav menu item to include dropdown indicators.
*
* Hook: 'wp_page_menu'
*
* @param string $output The menu output.
* @since 1.0.0
*/
function blogsy_page_menu_output_modification( string $output ): string {
$dropdown_indicator = \Blogsy\Icon::get_svg( 'chevron-down', 'ui', [ 'size' => 17 ] );
// Get all pages with children.
$all_pages = get_pages();
foreach ( $all_pages as $page ) {
$children = get_pages( [ 'child_of' => $page->ID ] );
if ( ! empty( $children ) ) {
// Find and replace the page link in output.
$old_pattern = '/]*>' . preg_quote( $page->post_title, '/' ) . '<\/span><\/a>/';
$new_content = '';
$new_content .= '' . $page->post_title . '';
$new_content .= $dropdown_indicator;
$new_content .= '';
$new_content .= '';
$output = preg_replace( $old_pattern, $new_content, $output );
// Also add the has-children class to li element.
$output = str_replace(
'class="page_item page-item-' . $page->ID . '"',
'class="page_item page-item-' . $page->ID . ' page_item_has_children"',
$output
);
}
}
return $output;
}
add_filter( 'wp_page_menu', 'blogsy_page_menu_output_modification', 10, 2 );
/**
* Display social icons in social links menu.
*
* Hook: 'walker_nav_menu_start_el'
*
* @param string $item_output The menu item output.
* @param WP_Post $item Menu item object.
* @param int $depth Depth of the menu.
* @param stdClass $args wp_nav_menu() arguments.
* @return string $item_output The menu item output with social icon.
* @since 1.0.0
*/
function blogsy_nav_menu_social_icons( string $item_output, WP_Post $item, int $depth, stdClass $args ): string {
// Get supported social icons.
$social_icons = blogsy_social_links_icons();
// Change SVG icon inside social links menu if there is supported URL.
if ( false !== strpos( $args->menu_class, 'blogsy-social-icons' ) ) {
foreach ( $social_icons as $attr => $value ) {
if ( false !== strpos( $item_output, (string) $attr ) ) {
$item_output = str_replace(
$args->link_after,
'' . \Blogsy\Icon::get_svg( $value, 'social', [ 'aria-hidden' => 'true' ] ),
$item_output
);
}
}
}
return $item_output;
}
add_filter( 'walker_nav_menu_start_el', 'blogsy_nav_menu_social_icons', 10, 4 );
/**
* Returns an array of supported social links (URL and icon name).
*
* @return array $social_links_icons
* @since 1.0.0
*/
function blogsy_social_links_icons(): array {
// Supported social links icons.
$social_links_icons = [
'500px.com' => '500px',
'amazon.com' => 'amazon',
'behance.net' => 'behance',
'digg.com' => 'digg',
'dribbble.com' => 'dribbble',
'deviantart' => 'deviantart',
'etsy.com' => 'etsy',
'facebook.com' => 'facebook',
'flipboard.com' => 'flipboard',
'flickr.com' => 'flickr',
'foursquare.com' => 'foursquare',
'github.com' => 'github',
'plus.google.com' => 'google-plus',
'instagram.com' => 'instagram',
'linkedin.com' => 'linkedin',
'mailto:' => 'mail',
'tel:' => 'phone',
'medium.com' => 'medium',
'pinterest.com' => 'pinterest',
'reddit.com' => 'reddit',
'skype.com' => 'skype',
'skype:' => 'skype',
'snapchat.com' => 'snapchat',
'soundcloud.com' => 'soundcloud',
'spotify.com' => 'spotify',
'tumblr.com' => 'tumblr',
'twitch.tv' => 'twitch',
'twitter.com' => 'twitter',
'x.com' => 'twitter',
'vimeo.com' => 'vimeo',
'xing.com' => 'xing',
'vk.com' => 'vkontakte',
'youtube.com' => 'youtube',
'yelp.com' => 'yelp',
'wa.me' => 'whatsapp',
'tiktok.com' => 'tiktok',
'stackoverflow.com' => 'stackoverflow',
'rss.com' => 'rss',
't.me' => 'telegram',
'discord.com' => 'discord',
'wechat.com' => 'wechat',
'qq.com' => 'qq',
'bilibili.tv' => 'bilibili',
'threads.net' => 'threads',
'linktr.ee' => 'linktree',
'rumble.com' => 'rumble',
'mastodon.social' => 'mastodon',
'bsky.app' => 'bluesky',
'bluesky.app' => 'bluesky',
'bsky.social' => 'bluesky',
'gemspace.com' => 'gemspace',
'lifegroupchat.com' => 'lifegroupchat',
];
/**
* Filter Blogsy social links icons.
*
* @since 1.0.0
* @param array $social_links_icons Array of social links icons.
*/
return apply_filters( 'blogsy_social_links_icons', $social_links_icons );
}
/**
* Remove dark mode widgets if dark mode is disabled.
*
* Hook: 'blogsy_main_header_widgets'
*
* @param array $widgets Header widgets.
* @return array $widgets Filtered header widgets.
* @since 1.0.0
*/
function blogsy_filter_main_header_widgets( array $widgets ): array {
if ( ! Helper::get_option( 'dark_mode' ) ) {
unset( $widgets['darkmode'] );
}
return $widgets;
}
add_filter( 'blogsy_main_header_widgets', 'blogsy_filter_main_header_widgets', 10, 1 );
/**
* Remove dark mode widgets if dark mode is disabled from header.
*
* Hook: 'blogsy_main_header_selected_widgets'
*
* @param array $widgets Header widgets.
* @return array $widgets Filtered header widgets.
* @since 1.0.0
*/
function blogsy_filter_main_header_selected_widgets( array $widgets ): array {
if ( ! Helper::get_option( 'dark_mode' ) ) {
foreach ( $widgets as $key => $item ) {
if ( isset( $item['type'] ) && 'darkmode' === $item['type'] ) {
unset( $widgets[ $key ] );
break;
}
}
}
return $widgets;
}
add_filter( 'blogsy_main_header_selected_widgets', 'blogsy_filter_main_header_selected_widgets' );
/**
* Ajax handler to load stories.
*
* @since 1.0.0
*/
function blogsy_stories_ajax_call() {
// Security check for the AJAX nonce.
check_ajax_referer( 'blogsy_story', '_wpnonce' );
// Get input data, always sanitize when handling input.
$story_ids = isset( $_POST['storyIds'] ) ? array_map( 'absint', (array) $_POST['storyIds'] ) : [];
$post_per_page = $_POST['inner_count'] ?? Helper::get_option( 'stories_max_inner_items', 4 );
$order = explode( '-', Helper::get_option( 'stories_orderby' ) );
// Always validate/sanitize input.
if ( empty( $story_ids ) ) {
wp_send_json_error( esc_html__( 'No stories found', 'blogsy' ) );
}
$query_args = [
'post_type' => 'post',
'post_status' => 'publish',
'no_found_rows' => true,
'posts_per_page' => absint( $post_per_page ),
'orderby' => $order[0] ?? 'date',
'order' => strtoupper( $order[1] ) ?? 'DESC',
];
$stories_elements = Helper::get_option( 'stories_elements' );
$success_flag = false;
ob_start();
foreach ( $story_ids as $cat_id ) {
if ( ! $cat_id ) {
continue;
}
$query_args['cat'] = $cat_id;
$query_instance = new WP_Query( apply_filters( 'blogsy_query_args_filter', $query_args ) );
if ( $query_instance->have_posts() ) {
$success_flag = true;
?>