| 1 |
<?php |
| 2 |
/** |
| 3 |
* Frequently Bought Together — Frontend widget template (Config B, checkbox list). |
| 4 |
* |
| 5 |
* Main product renders first as a disabled "this item" row; the rest are checkable |
| 6 |
* companions. Every row renders through frontend-widget-row.php, fed by |
| 7 |
* Cartflows_Fbt_Frontend::get_row_data(). A single button submits the bundle. |
| 8 |
* |
| 9 |
* @package cartflows |
| 10 |
* @var array<int, WC_Product> $products Companion products, stock-filtered by the caller. |
| 11 |
* @var array{enabled: string, source: string, product_ids: array<int, int>, add_separately: string, selection: string, position: string, custom_qty: string, product_qty: array<int, int>, ai_product_ids: array<int, int>} $fbt_settings Full FBT settings blob. |
| 12 |
*/ |
| 13 |
|
| 14 |
if ( ! defined( 'ABSPATH' ) ) { |
| 15 |
exit; |
| 16 |
} |
| 17 |
|
| 18 |
if ( empty( $products ) ) { |
| 19 |
return; |
| 20 |
} |
| 21 |
|
| 22 |
$fbt_frontend = Cartflows_Fbt_Frontend::get_instance(); |
| 23 |
$fbt_source = wc_get_product( get_the_ID() ); |
| 24 |
$fbt_source_id = $fbt_source ? (int) $fbt_source->get_id() : 0; |
| 25 |
$fbt_source_price = $fbt_source ? (float) wc_get_price_to_display( $fbt_source ) : 0.0; |
| 26 |
$fbt_show_qty = 'yes' === $fbt_settings['custom_qty']; |
| 27 |
$fbt_qty_map = $fbt_settings['product_qty']; |
| 28 |
|
| 29 |
$fbt_rows = array(); |
| 30 |
if ( $fbt_source ) { |
| 31 |
$fbt_rows[] = $fbt_frontend->get_row_data( $fbt_source, array( 'is_main' => true ) ); |
| 32 |
} |
| 33 |
foreach ( $products as $fbt_product ) { |
| 34 |
if ( ! $fbt_product instanceof WC_Product ) { |
| 35 |
continue; |
| 36 |
} |
| 37 |
$fbt_rows[] = $fbt_frontend->get_row_data( |
| 38 |
$fbt_product, |
| 39 |
array( |
| 40 |
'show_qty' => $fbt_show_qty, |
| 41 |
'qty' => isset( $fbt_qty_map[ $fbt_product->get_id() ] ) ? (int) $fbt_qty_map[ $fbt_product->get_id() ] : 1, |
| 42 |
) |
| 43 |
); |
| 44 |
} |
| 45 |
$fbt_rows = array_values( array_filter( $fbt_rows ) ); |
| 46 |
|
| 47 |
// Collapse the widget when it would otherwise show more than 3 companions. |
| 48 |
$fbt_visible_limit = 3; |
| 49 |
$fbt_companions = 0; |
| 50 |
foreach ( $fbt_rows as $fbt_i => $fbt_row ) { |
| 51 |
if ( ! $fbt_row['is_main'] ) { |
| 52 |
++$fbt_companions; |
| 53 |
$fbt_rows[ $fbt_i ]['is_extra'] = $fbt_companions > $fbt_visible_limit; |
| 54 |
} |
| 55 |
} |
| 56 |
$fbt_extras = max( 0, $fbt_companions - $fbt_visible_limit ); |
| 57 |
|
| 58 |
// Block themes (FSE) style buttons via wp-element-button; classic themes theme |
| 59 |
// WC's own Add-to-Cart button via the WC classes below. Pick the right hook. |
| 60 |
$fbt_button_class = wp_is_block_theme() |
| 61 |
? 'wcf-fbt-widget-add wp-element-button' |
| 62 |
: 'wcf-fbt-widget-add button alt single_add_to_cart_button'; |
| 63 |
?> |
| 64 |
<section class="wcf-fbt-widget<?php echo 'single' === $fbt_settings['selection'] ? ' is-single' : ''; ?><?php echo $fbt_extras > 0 ? ' is-collapsed' : ''; ?>" data-source-id="<?php echo esc_attr( (string) $fbt_source_id ); ?>"> |
| 65 |
<h3 class="wcf-fbt-widget-title"><?php esc_html_e( 'Frequently bought together', 'cartflows' ); ?></h3> |
| 66 |
<div class="wcf-fbt-widget-list"> |
| 67 |
<?php |
| 68 |
foreach ( $fbt_rows as $fbt_row ) { |
| 69 |
include CARTFLOWS_FBT_DIR . 'templates/frontend-widget-row.php'; |
| 70 |
} |
| 71 |
?> |
| 72 |
</div> |
| 73 |
<?php if ( $fbt_extras > 0 ) : ?> |
| 74 |
<button type="button" class="wcf-fbt-widget-toggle" data-extras="<?php echo esc_attr( (string) $fbt_extras ); ?>"> |
| 75 |
<?php |
| 76 |
printf( |
| 77 |
/* translators: %d: number of additional companion products. */ |
| 78 |
esc_html( _n( 'Show %d more', 'Show %d more', $fbt_extras, 'cartflows' ) ), |
| 79 |
esc_html( (string) $fbt_extras ) |
| 80 |
); |
| 81 |
?> |
| 82 |
</button> |
| 83 |
<?php endif; ?> |
| 84 |
<div class="wcf-fbt-widget-footer"> |
| 85 |
<div class="wcf-fbt-widget-total-wrap"> |
| 86 |
<div class="wcf-fbt-widget-total-label" data-role="wcf-fbt-label"><?php echo esc_html( sprintf( /* translators: %d: item count. */ _n( 'Total for %d item', 'Total for %d items', 1, 'cartflows' ), 1 ) ); ?></div> |
| 87 |
<div class="wcf-fbt-widget-total" data-role="wcf-fbt-total"><?php echo wp_kses_post( (string) wc_price( $fbt_source_price ) ); ?></div> |
| 88 |
</div> |
| 89 |
<button type="button" class="<?php echo esc_attr( $fbt_button_class ); ?>"><?php esc_html_e( 'Add to cart', 'cartflows' ); ?></button> |
| 90 |
</div> |
| 91 |
</section> |
| 92 |
|