Skip to content

Instantly share code, notes, and snippets.

@pramodjodhani
Created March 20, 2026 07:45
Show Gist options
  • Select an option

  • Save pramodjodhani/10d9c72a0ba09b381d0306d459a46c6f to your computer and use it in GitHub Desktop.

Select an option

Save pramodjodhani/10d9c72a0ba09b381d0306d459a46c6f to your computer and use it in GitHub Desktop.
Iconic Sales booster: Frequently bought together - link product images.
<?php
/**
* Iconic Sales booster: Frequently bought together - link product images.
*/
// 1) AJAX: return permalink for a given product ID.
add_action( 'wp_ajax_iconic_wsb_fbt_get_permalink', 'iconic_wsb_fbt_get_permalink' );
add_action( 'wp_ajax_nopriv_iconic_wsb_fbt_get_permalink', 'iconic_wsb_fbt_get_permalink' );
function iconic_wsb_fbt_get_permalink() {
$product_id = isset( $_POST['product_id'] ) ? absint( $_POST['product_id'] ) : 0;
if ( ! $product_id ) {
wp_send_json_error( array( 'message' => 'Missing product_id' ) );
}
$url = '';
if ( function_exists( 'wc_get_product' ) ) {
$product = wc_get_product( $product_id );
if ( $product ) {
$url = $product->get_permalink();
}
}
if ( ! $url ) {
$url = get_permalink( $product_id );
}
if ( ! $url ) {
wp_send_json_error( array( 'message' => 'Could not resolve permalink' ) );
}
wp_send_json_success( array( 'url' => $url ) );
}
// 2) Frontend: click handler + AJAX redirect.
add_action( 'wp_footer', function () {
if ( ! is_admin() ) {
global $post;
$post_content = '';
if ( isset( $post ) && is_object( $post ) ) {
$post_content = $post->post_content;
}
// Only load on pages where the FBT module is likely rendered.
$should_load = is_product() || is_cart() || is_checkout()
|| has_shortcode( $post_content, 'iconic_wsb_fbt' )
|| ( false !== strpos( $post_content, 'wp:iconic-wsb/fbt' ) );
if ( ! $should_load ) {
return;
}
wp_enqueue_script( 'jquery' );
wp_localize_script(
'jquery',
'iconicWsbFbtPermalinkVars',
array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'iconic_wsb_fbt_permalink_nonce' ),
)
);
?>
<script>
jQuery(function($){
const selector = '.iconic-wsb-product-bumps__images .iconic-wsb-product-bumps__image[data-product-id]';
// Fetch product URLs on page load and store in data attribute
$(selector).each(function() {
const $li = $(this);
const productId = String($li.data('product-id') || $li.attr('data-product-id') || '');
if (productId && !$li.attr('data-product-url')) {
$.ajax({
url: iconic_wsb_frontend_vars.ajax_url,
type: 'POST',
dataType: 'json',
data: {
action: 'iconic_wsb_fbt_get_permalink',
product_id: productId,
nonce: iconic_wsb_frontend_vars.nonce
}
}).done(function(resp){
if (resp && resp.success && resp.data && resp.data.url) {
$li.attr('data-product-url', resp.data.url);
}
});
}
});
// Make it keyboard-focusable (template doesn't add this).
$(document).on('mouseenter', selector, function(){
$(this).attr('tabindex', '0');
});
$(document).on('click', selector, function(e){
const $li = $(this);
const productUrl = $li.attr('data-product-url');
if (productUrl) {
window.location = productUrl;
return;
}
// Fallback if click happens before AJAX finishes or if dynamically added
const productId = String($li.data('product-id') || $li.attr('data-product-id') || '');
if (!productId) return;
// Prevent spamming requests on double-click.
if ($li.data('wsbFbtLinking')) return;
$li.data('wsbFbtLinking', true);
$.ajax({
url: iconicWsbFbtPermalinkVars.ajaxUrl,
type: 'POST',
dataType: 'json',
data: {
action: 'iconic_wsb_fbt_get_permalink',
product_id: productId,
nonce: iconicWsbFbtPermalinkVars.nonce
}
}).done(function(resp){
if (resp && resp.success && resp.data && resp.data.url) {
$li.attr('data-product-url', resp.data.url);
window.location = resp.data.url;
}
}).always(function(){
$li.data('wsbFbtLinking', false);
});
});
// Optional: Enter/Space to click when focused.
$(document).on('keydown', selector, function(e){
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
$(this).trigger('click');
}
});
// Cursor hint
if (!document.getElementById('iconic-wsb-fbt-link-style')) {
const style = document.createElement('style');
style.id = 'iconic-wsb-fbt-link-style';
style.textContent = selector + '{ cursor: pointer; }';
document.head.appendChild(style);
}
});
</script>
<?php
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment