1 ) {
$enabled_buttons = array_values( array_diff( $enabled_buttons, array( 'google_preferred' ) ) );
$google_section = true;
}
}
if ( empty( $enabled_buttons ) ) {
return '';
}
/*
* Compact mode needs something to compact (v2.6.0). With a single
* button, "one Share button that opens the rest" hid that button
* behind a toggle that opened nothing else.
*/
if ( count( $enabled_buttons ) + ( $google_section ? 1 : 0 ) < 2 ) {
$compact_mode = 'disabled';
}
// Determine if we use section titles (override global title).
// Mixed order always uses the general title since groups are interleaved.
$use_section_titles = ( ! empty( $ai_section_title ) || ! empty( $social_section_title ) ) && 'ayudawp_mixed' !== $button_order;
// Determine CSS classes.
$container_classes = array( 'ayudawp-share-buttons' );
if ( 'center' === $button_alignment ) {
$container_classes[] = 'ayudawp-aiss-centered';
}
if ( ! $separator_top ) {
$container_classes[] = 'no-separator-top';
}
if ( ! $separator_bottom ) {
$container_classes[] = 'no-separator-bottom';
}
// Size class.
if ( 'normal' !== $button_size ) {
$container_classes[] = 'size-' . $button_size;
}
if ( 'icons-only' === $color_style ) {
$container_classes[] = 'icons-only';
$container_classes[] = $icon_style;
$show_icons = true;
} elseif ( 'minimal' !== $color_style ) {
$container_classes[] = $color_style;
}
if ( $show_icons && 'icons-only' !== $color_style ) {
$container_classes[] = 'with-icons';
}
/*
* Mobile compact mode (v2.5.0). Everything is decided here in PHP and
* applied by CSS inside the mobile breakpoint, so the desktop render is
* byte-for-byte what it was and the extra markup costs one button. The
* JS only flips `is-expanded` and the aria state.
*/
if ( 'disabled' !== $compact_mode ) {
$container_classes[] = 'is-mobile-compact';
$container_classes[] = 'compact-' . $compact_mode;
}
$style_class = implode( ' ', $container_classes );
self::$uid++;
$block_id = 'ayudawp-aiss-share-' . self::$uid;
// Custom color inline style.
$custom_style = '';
if ( 'custom' === $color_style && ! empty( $custom_bg ) ) {
$custom_style = sprintf(
' style="--ayudawp-custom-bg:%s;--ayudawp-custom-text:%s;"',
esc_attr( $custom_bg ),
esc_attr( ! empty( $custom_text ) ? $custom_text : '#ffffff' )
);
}
/*
* data-post-id (v2.5.0) so click tracking knows which post it is
* counting without guessing from the theme's `article id="post-N"`,
* which only some themes emit.
*/
$block_post_id = null === $post_id ? get_the_ID() : (int) $post_id;
$post_id_attr = $block_post_id ? ' data-post-id="' . esc_attr( (string) $block_post_id ) . '"' : '';
$html = '
';
// Global title (only if no section titles). Carries an id so the
// buttons group can point at it with aria-labelledby (v2.5.0).
$global_title_id = '';
if ( ! $use_section_titles && ! empty( trim( $title_text ) ) ) {
$global_title_id = $block_id . '-title';
$html .= ayudawp_aiss_open_tag( $title_style, 'ayudawp-title', $global_title_id ) . esc_html( $title_text ) . ayudawp_aiss_close_tag( $title_style );
}
// Running index across every group, so "N visible + more" counts
// buttons in render order and not per section.
$rendered = 0;
// Split buttons into groups for section titles.
if ( $use_section_titles ) {
$social_buttons_list = ayudawp_aiss_get_social_buttons();
$ai_buttons_list = ayudawp_aiss_get_ai_buttons();
$social_group = array_values( array_intersect( $enabled_buttons, $social_buttons_list ) );
$ai_group = array_values( array_intersect( $enabled_buttons, $ai_buttons_list ) );
// Determine display order (mixed never reaches here due to $use_section_titles check).
$groups = array();
if ( 'ayudawp_ai_first' === $button_order ) {
if ( ! empty( $ai_group ) ) {
$groups[] = array( 'title' => $ai_section_title, 'buttons' => $ai_group, 'kind' => 'ai' );
}
if ( ! empty( $social_group ) ) {
$groups[] = array( 'title' => $social_section_title, 'buttons' => $social_group, 'kind' => 'social' );
}
} else {
if ( ! empty( $social_group ) ) {
$groups[] = array( 'title' => $social_section_title, 'buttons' => $social_group, 'kind' => 'social' );
}
if ( ! empty( $ai_group ) ) {
$groups[] = array( 'title' => $ai_section_title, 'buttons' => $ai_group, 'kind' => 'ai' );
}
}
foreach ( $groups as $index => $group ) {
$group_id = $block_id . '-group-' . $index;
$title_id = '';
/*
* A section whose every button falls past the visible count is
* hidden along with its title, so the compact render never
* leaves a heading standing over nothing.
*/
$group_hidden = ( 'partial' === $compact_mode && $rendered >= $compact_visible );
if ( ! empty( $group['title'] ) ) {
$title_id = $group_id . '-title';
$section_class = $index > 0 ? ' ayudawp-section-title' : '';
if ( $group_hidden ) {
$section_class .= ' aiss-overflow';
}
$html .= ayudawp_aiss_open_tag( $title_style, 'ayudawp-title' . $section_class, $title_id ) . esc_html( $group['title'] ) . ayudawp_aiss_close_tag( $title_style );
} elseif ( $index > 0 ) {
$html .= '
';
}
$html .= '
';
foreach ( $group['buttons'] as $button ) {
$overflow = ( 'partial' === $compact_mode && $rendered >= $compact_visible );
$html .= self::ayudawp_get_button_html( $button, $url, $title, $options, $show_icons, $color_style, $seo_button_type, $overflow );
$rendered++;
}
$html .= '
';
}
} else {
$html .= '
';
foreach ( $enabled_buttons as $button ) {
$overflow = ( 'partial' === $compact_mode && $rendered >= $compact_visible );
$html .= self::ayudawp_get_button_html( $button, $url, $title, $options, $show_icons, $color_style, $seo_button_type, $overflow );
$rendered++;
}
$html .= '
';
}
// Google preferred source in a section of its own, last (v2.6.0).
if ( $google_section ) {
$group_id = $block_id . '-google';
$title_id = '';
$group_hidden = ( 'partial' === $compact_mode && $rendered >= $compact_visible );
$google_title = isset( $options['_sc_google_title'] )
? $options['_sc_google_title']
: ( isset( $options['google_section_title'] ) ? $options['google_section_title'] : '' );
if ( '' !== trim( (string) $google_title ) ) {
$title_id = $group_id . '-title';
$html .= ayudawp_aiss_open_tag( $title_style, 'ayudawp-title ayudawp-section-title' . ( $group_hidden ? ' aiss-overflow' : '' ), $title_id ) . esc_html( $google_title ) . ayudawp_aiss_close_tag( $title_style );
} else {
// A visible line, unlike the spacer between the other groups:
// without a title it is what sets the section apart.
$html .= '
';
}
$html .= '
';
$html .= self::ayudawp_get_button_html( 'google_preferred', $url, $title, $options, $show_icons, $color_style, $seo_button_type, $group_hidden );
$html .= '
';
$rendered++;
}
// The compact toggle is rendered whenever the mode is on, but CSS only
// shows it inside the mobile breakpoint — and, in "N visible" mode,
// only when there is something hidden behind it.
if ( 'disabled' !== $compact_mode && ( 'single' === $compact_mode || $rendered > $compact_visible ) ) {
$html .= self::ayudawp_compact_toggle_html( $compact_mode, $block_id );
}
$html .= '
';
return $html;
}
/**
* Accessible name for a buttons group (v2.5.0)
*
* Points at the section title when there is one, so screen readers announce
* the group with the same words sighted visitors read. Without a title the
* group still needs a name, or `role="group"` announces an unnamed group.
*
* @since 2.5.0
* @param string $title_id Id of the title element, or '' when there is none.
* @param string $kind 'ai', 'social', 'mixed' or 'google' (v2.6.0).
* @return string Attribute string, starting with a space.
*/
private static function ayudawp_group_label_attr( $title_id, $kind ) {
if ( '' !== $title_id ) {
return ' aria-labelledby="' . esc_attr( $title_id ) . '"';
}
if ( 'ai' === $kind ) {
$label = __( 'Ask an AI assistant about this content', 'ai-share-summarize' );
} elseif ( 'social' === $kind ) {
$label = __( 'Share this content on social networks', 'ai-share-summarize' );
} elseif ( 'google' === $kind ) {
$label = __( 'Google preferred source', 'ai-share-summarize' );
} else {
$label = __( 'Share this content', 'ai-share-summarize' );
}
return ' aria-label="' . esc_attr( $label ) . '"';
}
/**
* Toggle that expands the compact mobile render (v2.5.0)
*
* Server-rendered so it works with page caching and needs no JS to exist;
* the script only toggles `is-expanded` on the block and keeps
* `aria-expanded` in sync. Hidden on desktop by CSS.
*
* @since 2.5.0
* @param string $mode 'single' or 'partial'.
* @param string $block_id Id of the share block it controls.
* @return string Toggle HTML.
*/
private static function ayudawp_compact_toggle_html( $mode, $block_id ) {
$label = 'single' === $mode
? __( 'Share', 'ai-share-summarize' )
: __( 'More', 'ai-share-summarize' );
/*
* No icon of its own: the caret comes from CSS, the same one the summary
* block uses to say "there is more behind this", and it rotates when the
* block opens. A share glyph here was indistinguishable from the native
* Share button, and an ellipsis was one more symbol for a gesture the
* interface already had a sign for.
*/
return ''
. ''
. '' . esc_html( $label ) . ' '
. '
';
}
/**
* Generate individual button HTML
*
* @param string $button Button type.
* @param string $url Current URL.
* @param string $title Current title.
* @param array $options Plugin options.
* @param bool $show_icons Whether to show icons.
* @param string $color_style Color style.
* @param string $seo_button_type Button HTML type ('link' or 'button').
* @param bool $overflow Whether this button hides behind the mobile
* compact toggle (v2.5.0).
* @return string Button HTML.
*/
public static function ayudawp_get_button_html( $button, $url, $title, $options, $show_icons = false, $color_style = 'default', $seo_button_type = 'link', $overflow = false ) {
$twitter_handle = isset( $options['twitter_handle'] ) ? $options['twitter_handle'] : '';
$custom_text = isset( $options['custom_text'] ) ? $options['custom_text'] : '';
$prompt = isset( $options['default_prompt'] ) ? $options['default_prompt'] : ayudawp_aiss_get_default_prompt();
$mastodon_instance = isset( $options['mastodon_instance'] ) ? $options['mastodon_instance'] : 'mastodon.social';
/*
* UTM tagging (v2.5.0) applies to the site's own URL, the one that
* travels to the destination, and is built per platform because
* utm_source is the platform key. Off by default, in which case this
* returns $url untouched.
*/
$url = ayudawp_aiss_add_utm( $url, $button, $options );
$full_prompt = $prompt;
if ( ! empty( $custom_text ) ) {
$full_prompt .= ' ' . $custom_text;
}
$full_prompt .= ' Source: ' . $url;
// Ensure mastodon instance has a fallback.
if ( empty( $mastodon_instance ) ) {
$mastodon_instance = 'mastodon.social';
}
$buttons_config = array(
// Social platforms.
'twitter' => array(
'label' => 'X (Twitter)',
'url' => 'https://twitter.com/intent/tweet?text=' . urlencode( $title . ' ' . $twitter_handle ) . '&url=' . urlencode( $url ),
'class' => 'twitter',
),
'linkedin' => array(
'label' => 'LinkedIn',
'url' => 'https://www.linkedin.com/sharing/share-offsite/?url=' . urlencode( $url ),
'class' => 'linkedin',
),
'facebook' => array(
'label' => 'Facebook',
'url' => 'https://www.facebook.com/sharer/sharer.php?u=' . urlencode( $url ),
'class' => 'facebook',
),
'telegram' => array(
'label' => 'Telegram',
'url' => 'https://t.me/share/url?url=' . urlencode( $url ) . '&text=' . urlencode( $title ),
'class' => 'telegram',
),
'whatsapp' => array(
'label' => 'WhatsApp',
'url' => 'https://api.whatsapp.com/send?text=' . urlencode( $title . ' ' . $url ),
'class' => 'whatsapp',
),
'email' => array(
'label' => 'Email',
'url' => 'mailto:?subject=' . urlencode( $title ) . '&body=' . urlencode( $url ),
'class' => 'email',
),
'raindrop' => array(
'label' => 'Raindrop',
'url' => 'https://app.raindrop.io/add?link=' . urlencode( $url ) . '&title=' . urlencode( $title ),
'class' => 'raindrop',
),
'reddit' => array(
'label' => 'Reddit',
'url' => 'https://www.reddit.com/submit?url=' . urlencode( $url ) . '&title=' . urlencode( $title ),
'class' => 'reddit',
),
'bluesky' => array(
'label' => 'Bluesky',
'url' => 'https://bsky.app/intent/compose?text=' . urlencode( $title . ' ' . $url ),
'class' => 'bluesky',
),
'line' => array(
'label' => 'LINE',
'url' => 'https://social-plugins.line.me/lineit/share?url=' . urlencode( $url ),
'class' => 'line',
),
'mastodon' => array(
'label' => 'Mastodon',
'url' => 'https://' . $mastodon_instance . '/share?text=' . urlencode( $title . ' ' . $url ),
'class' => 'mastodon',
),
'threads' => array(
'label' => 'Threads',
'url' => 'https://www.threads.net/intent/post?text=' . urlencode( $title . ' ' . $url ),
'class' => 'threads',
),
'pinterest' => array(
'label' => 'Pinterest',
'url' => 'https://pinterest.com/pin/create/button/?url=' . urlencode( $url ) . '&description=' . urlencode( $title ),
'class' => 'pinterest',
),
// Browser actions (v2.5.0). Their "url" is the page itself: the
// script copies it to the clipboard or hands it to the operating
// system share sheet. They are always rendered as