rtsb_name = esc_html__( 'Product Images', 'shopbuilder' ); $this->rtsb_base = 'rtsb-product-image'; parent::__construct( $data, $args ); $this->the_hooks(); } /** * Widget Field * * @return array */ public function widget_fields() { return $this->modify_widget_fields(); } /** * Widget Field * * @return array */ public function modify_widget_fields() { $fields = ProductImagesSettings::widget_fields( $this ); $extra_controls['image_border'] = [ 'mode' => 'group', 'type' => 'border', 'selector' => $this->selectors['image_border'], 'size_units' => [ 'px' ], 'fields_options' => [ 'border' => [ 'label' => esc_html__( 'Border', 'shopbuilder' ), 'label_block' => true, ], 'color' => [ 'label' => esc_html__( 'Border Color', 'shopbuilder' ), ], ], ]; $fields = Fns::insert_controls( 'image_width', $fields, $extra_controls, true ); return $fields; } /** * Widget Field. * * @return void */ public function init_scripts() { ?> get_settings_for_display(); if ( ! empty( $controllers['gallery_thumbs_column']['size'] ) ) { $col = absint( $controllers['gallery_thumbs_column']['size'] ); } return $col; } /** * Thumbnail slider js options. * * @param array $options Options. * * @return array */ public function thumbnail_slider_js_options( $options ) { $controllers = $this->get_settings_for_display(); if ( ! empty( $controllers['gallery_thumbs_column']['size'] ) ) { $options['slidesPerView'] = absint( $controllers['gallery_thumbs_column']['size'] ); } if ( ! empty( $controllers['gallery_thumbs_column_gap']['size'] ) ) { $options['spaceBetween'] = $controllers['gallery_thumbs_column_gap']['size']; } return $options; } /** * Thumbnails columns. * * @param int $column Column. * * @return mixed */ public function thumbnails_columns( $column ) { $controllers = $this->get_settings_for_display(); $column = ! empty( $controllers['gallery_thumbs_column']['size'] ) ? $controllers['gallery_thumbs_column']['size'] : $column; return $column; } /** * Thumbnails columns. * * @param int $column Column. * * @return mixed */ public function thumbnails_columns_sm( $column ) { $controllers = $this->get_settings_for_display(); $column = ! empty( $controllers['gallery_thumbs_column_tablet']['size'] ) ? $controllers['gallery_thumbs_column_tablet']['size'] : $column; return $column; } /** * Thumbnails columns. * * @param int $column Column. * * @return mixed */ public function thumbnails_columns_xs( $column ) { $controllers = $this->get_settings_for_display(); $column = ! empty( $controllers['gallery_thumbs_column_mobile']['size'] ) ? $controllers['gallery_thumbs_column_mobile']['size'] : $column; return $column; } /** * Thumbnail position. * * @param string $position Position. * * @return string */ public function thumbnail_position( $position ) { if ( ! function_exists( 'rtwpvg' ) || ! rtwpvg()->active_pro() || ! ( BuilderFns::is_product() || BuilderFns::is_quick_views_page() ) ) { return $position; } $controllers = $this->get_settings_for_display(); $show_thumbnails = ! empty( $controllers['show_thumbnails'] ) ? $controllers['show_thumbnails'] : false; if ( ! $show_thumbnails && 'grid' !== ( $controllers['image_layout'] ?? '' ) ) { add_filter( 'rtwpvg_show_product_thumbnail_slider', '__return_false', 20 ); return 'bottom'; } return ! empty( $controllers['image_layout'] ) ? $controllers['image_layout'] : 'bottom'; } /** * Thumbnail position. * * @param string $position Position. * * @return string */ public function vg_thumbnail_position( $position ) { if ( ! rtsb()->has_pro() ) { return $position; } $controllers = $this->get_settings_for_display(); return ! empty( $controllers['image_layout'] ) ? $controllers['image_layout'] : 'bottom'; } /** * Whether the Variation Gallery lightbox trigger should render. * * The `rtsb/vg/lightbox` filter is a boolean gate (see the VG product-image * template). It must reflect the widget's "Show Lightbox Icon?" (show_zoom) * setting so disabling it actually hides the trigger — not the icon HTML, which * is always truthy and would keep the trigger visible. * * @param bool $show Whether to show the lightbox trigger. * @return bool */ public function vg_show_lightbox( $show ) { $controllers = $this->get_settings_for_display(); return ! empty( $controllers['show_zoom'] ); } /** * @param bool $lightbox Lightbox. * @return mixed */ public function vg_lightbox( $lightbox ) { $controllers = $this->get_settings_for_display(); // The icons control always returns a populated array (`value`/`library`), so // check the actual `value`; when it is cleared, fall back to the default SVG // instead of rendering an empty icon. return ! empty( $controllers['lightbox_icon']['value'] ) ? Fns::icons_manager( $controllers['lightbox_icon'] ) : $lightbox; } /** * @param string $position position text. * @return mixed */ public function vg_lightbox_position( $position ) { $controllers = $this->get_settings_for_display(); return ! empty( $controllers['vg_lightbox_position'] ) ? $controllers['vg_lightbox_position'] : $position; } /** * Enqueue the Font Awesome library required by the selected lightbox icon. * * Elementor only auto-loads icon fonts for icons rendered through its own widget * flow. The lightbox icon is injected into the Variation Gallery / WooCommerce * gallery markup via a filter, so on the front end its font is never enqueued and * the glyph renders empty — it appears in the editor only because Elementor always * loads Font Awesome there. Enqueue the matching library so the icon shows on the * front end. SVG icons carry no library and need no enqueue. * * @param array $icon Elementor icons control value. * @return void */ private function enqueue_lightbox_icon_font( $icon ) { if ( empty( $icon['library'] ) ) { return; } $handles = [ 'fa-solid' => 'elementor-icons-fa-solid', 'fa-regular' => 'elementor-icons-fa-regular', 'fa-brands' => 'elementor-icons-fa-brands', ]; if ( isset( $handles[ $icon['library'] ] ) ) { wp_enqueue_style( $handles[ $icon['library'] ] ); } } /** * Render Function * * @return void */ protected function render() { add_action( 'wp_footer', 'woocommerce_photoswipe' ); global $product, $post; $_product = $product; $product = Fns::get_product(); $controllers = $this->get_settings_for_display(); if ( empty( $controllers['show_module_badges'] ) ) { add_filter( 'rtsb/module/badges/show', '__return_false', 99 ); } // When "Show Thumbnails?" is off, hide the Variation Gallery thumbnail slider. $hide_vg_thumbnails = empty( $controllers['show_thumbnails'] ); if ( ! empty( $controllers['show_zoom'] ) && ! empty( $controllers['lightbox_icon'] ) ) { $this->enqueue_lightbox_icon_font( $controllers['lightbox_icon'] ); } $this->theme_support(); $controllers['lightbox_icon'] = Fns::icons_manager( $controllers['lightbox_icon'] ); $data = [ 'template' => 'elementor/single-product/product-images', 'controllers' => $controllers, ]; $this->the_hooks( $controllers ); if ( $hide_vg_thumbnails ) { add_filter( 'rtsb/vg/show/thumbnails', '__return_false' ); } Fns::load_template( $data['template'], $data ); if ( $hide_vg_thumbnails ) { remove_filter( 'rtsb/vg/show/thumbnails', '__return_false' ); } if ( $this->is_builder_mode() ) { $this->init_scripts(); } if ( empty( $controllers['show_module_badges'] ) ) { remove_filter( 'rtsb/module/badges/show', '__return_false', 99 ); } $this->theme_support( 'render_reset' ); $product = $_product; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } }