PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 1.10.0
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v1.10.0
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
merchant / inc / modules / quick-view / class-quick-view.php

class-quick-view.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 1.10.0, at inc/modules/quick-view/class-quick-view.php

826 lines 27.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Quick View.
5 *
6 * @package Merchant
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly
11 }
12
13 /**
14 * Quick View Class.
15 *
16 */
17 class Merchant_Quick_View extends Merchant_Add_Module {
18
19 /**
20 * Module ID.
21 *
22 */
23 const MODULE_ID = 'quick-view';
24
25 /**
26 * Is module preview.
27 *
28 */
29 public static $is_module_preview = false;
30
31 private static $instance = null;
32
33 /**
34 * Constructor.
35 *
36 */
37 public function __construct() {
38
39 // Module id.
40 $this->module_id = self::MODULE_ID;
41
42 // WooCommerce only.
43 $this->wc_only = true;
44
45 // Parent construct.
46 parent::__construct();
47
48 // Module section.
49 $this->module_section = 'convert-more';
50
51 // Module default settings.
52 $this->module_default_settings = array(
53 'button_type' => 'text',
54 'button_text' => __( 'Quick View', 'merchant' ),
55 'button_icon' => 'eye',
56 'button_position' => 'overlay',
57 'button-position-top' => 50,
58 'button-position-left' => 50,
59 'zoom_effect' => 1,
60 'show_quantity' => 1,
61 'place_product_description' => 'top',
62 'description_style' => 'short',
63 'place_product_image' => 'thumbs-at-left',
64 'show_buy_now_button' => false,
65 'show_suggested_products' => true,
66 'suggested_products_module' => 'bulk_discounts',
67 'suggested_products_placement' => 'after_add_to_cart',
68 );
69
70 // Mount preview url.
71 $preview_url = site_url( '/' );
72
73 if ( function_exists( 'wc_get_page_id' ) ) {
74 $preview_url = get_permalink( wc_get_page_id( 'shop' ) );
75 }
76
77 // Module data.
78 $this->module_data = Merchant_Admin_Modules::$modules_data[ self::MODULE_ID ];
79 $this->module_data[ 'preview_url' ] = $preview_url;
80
81 // Module options path.
82 $this->module_options_path = MERCHANT_DIR . 'inc/modules/' . self::MODULE_ID . '/admin/options.php';
83
84 // Is module preview page.
85 if ( is_admin() && parent::is_module_settings_page() ) {
86 self::$is_module_preview = true;
87
88 // Enqueue admin styles.
89 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_css' ) );
90
91 // Admin preview box.
92 add_filter( 'merchant_module_preview', array( $this, 'render_admin_preview' ), 10, 2 );
93
94 // Custom CSS.
95 // The custom CSS should be added here as well due to ensure preview box works properly.
96 add_filter( 'merchant_custom_css', array( $this, 'admin_custom_css' ) );
97
98 }
99
100 if ( Merchant_Modules::is_module_active( self::MODULE_ID ) && is_admin() ) {
101 // Init translations.
102 $this->init_translations();
103 }
104
105 if ( ! Merchant_Modules::is_module_active( self::MODULE_ID ) ) {
106 return;
107 }
108
109 // Return early if it's on admin but not in the respective module settings page.
110 if ( is_admin() && ! wp_doing_ajax() && ! parent::is_module_settings_page() ) {
111 return;
112 }
113
114 // Enqueue styles.
115 add_action( 'merchant_enqueue_before_main_css_js', array( $this, 'enqueue_css' ) );
116
117 // Enqueue scripts.
118 add_action( 'merchant_enqueue_after_main_css_js', array( $this, 'enqueue_scripts' ) );
119
120 // Localize script.
121 add_filter( 'merchant_localize_script', array( $this, 'localize_script' ) );
122
123 // Handle Botiga theme scripts for compatibility.
124 if ( defined( 'BOTIGA_PRO_URI' ) && defined( 'BOTIGA_PRO_VERSION' ) ) {
125 add_action( 'wp_enqueue_scripts', array( $this, 'modal_compatibility_with_botiga_theme' ) );
126 }
127
128 // Button Position.
129 $button_position = Merchant_Admin_Options::get( self::MODULE_ID, 'button_position', 'overlay' );
130
131 if ( 'before' === $button_position ) {
132 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'quick_view_button' ), 5 );
133 } elseif ( 'after' === $button_position ) {
134 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'quick_view_button' ), 15 );
135 } elseif ( 'overlay' === $button_position ) {
136 if ( merchant_is_kadence_active() ) {
137 add_filter( 'kadence_archive_content_wrap_start', array( $this, 'add_quick_view_button' ) );
138 } else {
139 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'quick_view_button' ), 15 );
140 }
141 }
142
143 // Inject quick view modal output on footer.
144 add_action( 'wp_footer', array( $this, 'modal_output' ) );
145
146 // Show Suggested Module
147 $suggested_placement = Merchant_Admin_Options::get( self::MODULE_ID, 'suggested_products_placement', 'after_add_to_cart' );
148 add_action( 'merchant_quick_view_' . $suggested_placement, array( $this, 'render_suggested_module_content' ), 10, 2 );
149
150 // Show Buy Now Module
151 add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'render_buy_now_button' ) );
152
153 // Custom CSS.
154 add_filter( 'merchant_custom_css', array( $this, 'frontend_custom_css' ) );
155
156 // Modal content ajax callback.
157 add_action( 'wp_ajax_merchant_quick_view_content', array( $this, 'modal_content_ajax_callback' ) );
158 add_action( 'wp_ajax_nopriv_merchant_quick_view_content', array( $this, 'modal_content_ajax_callback' ) );
159 }
160
161
162 public static function get_instance() {
163 if ( self::$instance === null ) {
164 self::$instance = new self();
165 }
166
167 return self::$instance;
168 }
169
170 /**
171 * Init translations.
172 *
173 * @return void
174 */
175 public function init_translations() {
176 $settings = $this->get_module_settings();
177 if ( ! empty( $settings['button_text'] ) ) {
178 Merchant_Translator::register_string( $settings['button_text'], esc_html__( 'Quick view button text', 'merchant' ) );
179 }
180 }
181
182 /**
183 * Concatenate the quick view button with the content start wrap.
184 *
185 * @return string
186 */
187 public function add_quick_view_button() {
188 return $this->quick_view_button() . '<div class="product-details content-bg entry-content-wrap">';
189 }
190
191 /**
192 * Admin enqueue CSS.
193 *
194 * @return void
195 */
196 public function admin_enqueue_css() {
197 $page = ( ! empty( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
198 $module = ( ! empty( $_GET['module'] ) ) ? sanitize_text_field( wp_unslash( $_GET['module'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
199
200 if ( 'merchant' === $page && self::MODULE_ID === $module ) {
201 wp_enqueue_style( 'merchant-' . self::MODULE_ID, MERCHANT_URI . 'assets/css/modules/' . self::MODULE_ID . '/quick-view.min.css', array(), MERCHANT_VERSION );
202 wp_enqueue_style( 'merchant-admin-' . self::MODULE_ID, MERCHANT_URI . 'assets/css/modules/' . self::MODULE_ID . '/admin/preview.min.css', array(), MERCHANT_VERSION );
203 }
204 }
205
206 /**
207 * Enqueue CSS.
208 *
209 * @return void
210 */
211 public function enqueue_css() {
212
213 // Specific module styles.
214 wp_enqueue_style( 'merchant-' . self::MODULE_ID, MERCHANT_URI . 'assets/css/modules/' . self::MODULE_ID . '/quick-view.min.css', array(), MERCHANT_VERSION );
215 }
216
217 /**
218 * Enqueue scripts.
219 *
220 * @return void
221 */
222 public function enqueue_scripts() {
223 wp_enqueue_script( 'zoom' );
224 wp_enqueue_script( 'flexslider' );
225 wp_enqueue_script( 'wc-single-product' );
226 wp_enqueue_script( 'wc-add-to-cart-variation' );
227
228 // Register and enqueue the main module script.
229 wp_enqueue_script( 'merchant-' . self::MODULE_ID, MERCHANT_URI . 'assets/js/modules/' . self::MODULE_ID . '/quick-view.min.js', array(), MERCHANT_VERSION, true );
230 }
231
232 /**
233 * Localize script with module settings.
234 *
235 * @param array $setting The merchant global object setting parameter.
236 * @return array $setting The merchant global object setting parameter.
237 */
238 public function localize_script( $setting ) {
239 $module_settings = $this->get_module_settings();
240
241 $setting[ 'quick_view' ] = true;
242 $setting[ 'quick_view_zoom' ] = $module_settings[ 'zoom_effect' ];
243
244 return $setting;
245 }
246
247 /**
248 * Enqueue botiga theme scripts.
249 *
250 * @return void
251 */
252 public function modal_compatibility_with_botiga_theme() {
253 if ( ! wp_script_is( 'botiga-product-swatch' ) ) {
254 wp_enqueue_script( 'botiga-product-swatch', BOTIGA_PRO_URI . 'assets/js/botiga-product-swatch.min.js', array(), BOTIGA_PRO_VERSION, true );
255 }
256
257 if ( ! wp_script_is( 'botiga-checkout-quantity-input' ) ) {
258 wp_enqueue_script( 'botiga-checkout-quantity-input', BOTIGA_PRO_URI . 'assets/js/botiga-checkout-quantity-input.min.js', array( 'jquery' ), BOTIGA_PRO_VERSION, true );
259 }
260 }
261
262 /**
263 * Render admin preview
264 *
265 * @param Merchant_Admin_Preview $preview
266 * @param string $module
267 *
268 * @return Merchant_Admin_Preview
269 */
270 public function render_admin_preview( $preview, $module ) {
271 if ( self::MODULE_ID === $module ) {
272 ob_start();
273 self::admin_preview_content();
274 $content = ob_get_clean();
275
276 // HTML.
277 $preview->set_html( $content );
278
279 // Button Type.
280 $preview->set_class( 'button_type', '.merchant-quick-view-button', array( 'icon', 'icon-text', 'text' ) );
281
282 // Button Text.
283 $preview->set_text( 'button_text', '.button-text' );
284
285 // Button Icon.
286 $preview->set_svg_icon( 'button_icon', '.quick-view-icon' );
287
288 // Button Position.
289 $preview->set_class( 'button_position', '.merchant-quick-view-preview', array( 'before', 'after', 'overlay' ) );
290
291 }
292
293 return $preview;
294 }
295
296 /**
297 * Admin preview content.
298 *
299 * @return void
300 */
301 public function admin_preview_content() {
302 $settings = $this->get_module_settings();
303
304 ?>
305
306 <div class="merchant-quick-view-preview <?php echo esc_attr( $settings[ 'button_position' ] ); ?>">
307 <div class="image-wrapper">
308 <div class="button-position button-position-overlay">
309 <?php $this->admin_preview_quick_view_button(); ?>
310 </div>
311 </div>
312 <h3><?php echo esc_html__( 'Product Title', 'merchant' ); ?></h3>
313 <p><?php echo esc_html__( 'The product description normally is displayed here.', 'merchant' ); ?></p>
314 <div class="button-position button-position-before">
315 <?php $this->admin_preview_quick_view_button(); ?>
316 </div>
317 <div>
318 <a href="#" class="add_to_cart_button"><?php echo esc_html__( 'Add To Cart', 'merchant' ); ?></a>
319 </div>
320 <div class="button-position button-position-after">
321 <?php $this->admin_preview_quick_view_button(); ?>
322 </div>
323
324 </div>
325
326 <?php
327 }
328
329 /**
330 * Admin preview quick view button.
331 *
332 * @return void
333 */
334 public function admin_preview_quick_view_button() {
335 $settings = $this->get_module_settings();
336
337 ?>
338
339 <a href="#" class="merchant-quick-view-button <?php echo esc_attr( $settings[ 'button_type' ] ); ?>">
340 <span class="button-type button-type-icon">
341 <span class="quick-view-icon">
342 <?php echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $settings[ 'button_icon' ] ), merchant_kses_allowed_tags( array(), false ) ); ?>
343 </span>
344 </span>
345 <span class="button-type button-type-icon-text">
346 <span class="quick-view-icon">
347 <?php echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $settings[ 'button_icon' ] ), merchant_kses_allowed_tags( array(), false ) ); ?>
348 </span>
349 <span class="button-text"><?php echo esc_html( $settings[ 'button_text' ] ); ?></span>
350 </span>
351 <span class="button-type button-type-text">
352 <span class="button-text"><?php echo esc_html( $settings[ 'button_text' ] ); ?></span>
353 </span>
354 </a>
355
356 <?php
357 }
358
359 /**
360 * Modal content ajax callback.
361 * TODO: Render the output through templates files.
362 *
363 * @return void
364 */
365 public function modal_content_ajax_callback() {
366 check_ajax_referer( 'merchant-nonce', 'nonce' );
367
368 if ( ! isset( $_POST['product_id'] ) || ! function_exists( 'wc_get_product' ) ) {
369 wp_send_json_error();
370 }
371
372 $args = array(
373 'product_id' => absint( $_POST['product_id'] ),
374 );
375
376 global $product;
377
378 $settings = $this->get_module_settings();
379 $product = wc_get_product( $args['product_id'] );
380
381 if ( is_wp_error( $product ) || empty( $product ) ) {
382 wp_send_json_error();
383 }
384
385 $product_id = $product->get_id();
386 $hide_quantity = ( empty( $settings[ 'show_quantity' ] ) ) ? 'merchant-hide-quantity' : '';
387
388 ob_start();
389 ?>
390 <div id="product-<?php echo absint( $product_id ); ?>" <?php wc_product_class( '', $product ); ?>>
391 <div class="merchant-quick-view-row">
392 <div class="merchant-quick-view-column">
393 <div class="merchant-quick-view-product-gallery">
394 <?php woocommerce_show_product_images(); ?>
395 </div>
396 </div>
397
398 <div class="merchant-quick-view-column">
399 <div class="merchant-quick-view-summary product-gallery-summary">
400 <div class="merchant-quick-view-product-title">
401 <h2 class="product_title entry-title"><?php echo esc_html( $product->get_title() ); ?></h2>
402 </div>
403
404 <?php if ( 0 !== $product->get_average_rating() ) : ?>
405 <div class="merchant-quick-view-product-rating">
406 <div class="woocommerce-product-rating">
407 <?php echo wp_kses( wc_get_rating_html( $product->get_average_rating() ), merchant_kses_allowed_tags() ); ?>
408 </div>
409 </div>
410 <?php endif; ?>
411
412 <div class="merchant-quick-view-product-price">
413 <div class="price"><?php echo wp_kses( $product->get_price_html(), merchant_kses_allowed_tags() ); ?></div>
414 </div>
415
416 <?php if ( 'top' === $settings[ 'place_product_description' ] ) : ?>
417 <?php
418 /**
419 * Hook 'merchant_quick_view_before_product_description'
420 *
421 * @since 1.9.14
422 */
423 do_action( 'merchant_quick_view_before_product_description' );
424
425 $description = $settings[ 'description_style' ] === 'full' ? $product->get_description() : $product->get_short_description();
426
427 /**
428 * `merchant_quick_view_description`
429 *
430 * @since 1.9.16
431 */
432 $description = apply_filters( 'merchant_quick_view_description', $description );
433 ?>
434 <div class="merchant-quick-view-product-excerpt">
435 <?php echo wp_kses_post( $description ); ?>
436 </div>
437
438 <?php
439 /**
440 * Hook 'merchant_quick_view_before_product_description'
441 *
442 * @since 1.9.14
443 */
444 do_action( 'merchant_quick_view_after_product_description' );
445 ?>
446 <?php endif; ?>
447
448 <?php
449 /**
450 * Hook 'merchant_quick_view_before_add_to_cart'
451 *
452 * @since 1.9.14
453 */
454 do_action( 'merchant_quick_view_before_add_to_cart', $product, $settings );
455 ?>
456 <div class="merchant-quick-view-product-add-to-cart <?php echo esc_attr( $hide_quantity ); ?>">
457 <?php woocommerce_template_single_add_to_cart(); ?>
458 </div>
459
460 <?php
461 /**
462 * Hook 'merchant_quick_view_after_add_to_cart'
463 *
464 * @since 1.9.14
465 */
466 do_action( 'merchant_quick_view_after_add_to_cart', $product, $settings );
467 ?>
468
469 <?php if ( 'bottom' === $settings[ 'place_product_description' ] ) : ?>
470 <?php
471 /**
472 * Hook 'merchant_quick_view_before_product_description'
473 *
474 * @since 1.9.14
475 */
476 do_action( 'merchant_quick_view_before_product_description' );
477
478 $description = $settings[ 'description_style' ] === 'full' ? $product->get_description() : $product->get_short_description();
479
480 /**
481 * `merchant_quick_view_description`
482 *
483 * @since 1.9.16
484 */
485 $description = apply_filters( 'merchant_quick_view_description', $description );
486 ?>
487 <div class="merchant-quick-view-product-excerpt">
488 <?php echo wp_kses_post( $description ); ?>
489 </div>
490
491 <?php
492 /**
493 * Hook 'merchant_quick_view_after_product_description'
494 *
495 * @since 1.9.14
496 */
497 do_action( 'merchant_quick_view_after_product_description' );
498 ?>
499 <?php endif; ?>
500 <div class="merchant-quick-view-product-meta">
501 <?php woocommerce_template_single_meta(); ?>
502 </div>
503
504 <?php
505 /**
506 * Hook 'merchant_quick_view_after_product_excerpt'
507 *
508 * @since 1.0.0
509 */
510 do_action( 'merchant_quick_view_after_product_meta' );
511 ?>
512 </div>
513 </div>
514 </div>
515 </div>
516 <?php
517 $content = ob_get_contents();
518
519 ob_get_clean();
520
521 wp_send_json_success( $content );
522 }
523
524 /**
525 * Modal output.
526 * TODO: Render the output through templates files.
527 *
528 * @return void
529 */
530 public function modal_output() {
531 $settings = $this->get_module_settings();
532 ?>
533 <div class="single-product merchant-quick-view-modal merchant-quick-view-<?php echo esc_attr( $settings[ 'place_product_image' ] ); ?>">
534 <div class="merchant-quick-view-overlay"></div>
535 <div class="merchant-quick-view-loader">
536 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
537 <path opacity="0.4" d="M478.71 364.58zm-22 6.11l-27.83-15.9a15.92 15.92 0 0 1-6.94-19.2A184 184 0 1 1 256 72c5.89 0 11.71.29 17.46.83-.74-.07-1.48-.15-2.23-.21-8.49-.69-15.23-7.31-15.23-15.83v-32a16 16 0 0 1 15.34-16C266.24 8.46 261.18 8 256 8 119 8 8 119 8 256s111 248 248 248c98 0 182.42-56.95 222.71-139.42-4.13 7.86-14.23 10.55-22 6.11z" />
538 <path d="M271.23 72.62c-8.49-.69-15.23-7.31-15.23-15.83V24.73c0-9.11 7.67-16.78 16.77-16.17C401.92 17.18 504 124.67 504 256a246 246 0 0 1-25 108.24c-4 8.17-14.37 11-22.26 6.45l-27.84-15.9c-7.41-4.23-9.83-13.35-6.2-21.07A182.53 182.53 0 0 0 440 256c0-96.49-74.27-175.63-168.77-183.38z" />
539 </svg>
540 </div>
541 <div class="merchant-quick-view-inner">
542 <a href="#" class="merchant-quick-view-close-button" title="<?php echo esc_attr__( 'Close quick view modal', 'merchant' ); ?>">
543 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
544 <path d="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z"/>
545 </svg>
546 </a>
547 <div class="merchant-quick-view-content"></div>
548 </div>
549 </div>
550 <?php
551 }
552
553 /**
554 * Quick view button.
555 *
556 * @return void
557 */
558 public function quick_view_button() {
559 global $product;
560
561 $settings = $this->get_module_settings();
562 $product_id = $product->get_id();
563
564 $button_text_html = '';
565 $button_icon_html = '';
566
567 if ( 'icon' === $settings[ 'button_type' ] || 'icon-text' === $settings[ 'button_type' ] ) {
568 $button_icon_html = Merchant_SVG_Icons::get_svg_icon( $settings[ 'button_icon' ] );
569 }
570
571 if ( 'text' === $settings[ 'button_type' ] || 'icon-text' === $settings[ 'button_type' ] ) {
572 $button_text_html = '<span>' . Merchant_Translator::translate( $settings[ 'button_text' ] ) . '</span>';
573 }
574
575 ?>
576 <a href="#" class="button wp-element-button merchant-quick-view-button merchant-quick-view-position-<?php echo esc_attr( $settings[ 'button_position' ] ); ?>" data-product-id="<?php echo absint( $product_id ); ?>"><?php echo wp_kses( $button_icon_html, merchant_kses_allowed_tags( array(), false ) ) . wp_kses_post( $button_text_html ); ?></a>
577 <?php
578 }
579
580 /**
581 * Renders the Buy Now button.
582 *
583 * @return void
584 */
585 public function render_buy_now_button() {
586 if ( ! Merchant_Modules::is_module_active( Merchant_Buy_Now::MODULE_ID ) ) {
587 return;
588 }
589
590 // Don't include on Single Product
591 if ( ! did_action( 'merchant_quick_view_before_add_to_cart' ) ) {
592 return;
593 }
594
595 $show_buy_now = (bool) Merchant_Admin_Options::get( $this->module_id, 'show_buy_now_button', false );
596 if ( ! $show_buy_now ) {
597 return;
598 }
599
600 global $product;
601
602 $text = Merchant_Admin_Options::get( Merchant_Buy_Now::MODULE_ID, 'button-text', esc_html__( 'Buy Now', 'merchant' ) );
603
604 $_wrapper_classes = array();
605 $_wrapper_classes[] = $product->get_type() === 'variable' ? 'disabled' : '';
606
607 /**
608 * Hook 'merchant_module_buy_now_wrapper_class'
609 *
610 * @since 1.8
611 */
612 $wrapper_classes = apply_filters( 'merchant_module_buy_now_wrapper_class', $_wrapper_classes );
613 ?>
614 <!-- Don't define type="submit" because it creates issue with block themes. The button is inside the form, so by default the type is already "submit". -->
615 <button name="merchant-buy-now" value="<?php echo absint( $product->get_ID() ); ?>" class="button alt wp-element-button merchant-buy-now-button <?php echo esc_attr( implode( ' ', $wrapper_classes ) ); ?>"><?php echo esc_html( Merchant_Translator::translate( $text ) ); ?></button>
616 <?php
617 }
618
619 /**
620 * Renders the suggested module content based on the provided settings.
621 *
622 * @param $product
623 * @param $settings
624 *
625 * @return void
626 */
627 public function render_suggested_module_content( $product, $settings ) {
628 $show_suggested = (bool) Merchant_Admin_Options::get( $this->module_id, 'show_suggested_products', true );
629
630 if ( ! $show_suggested || empty( $product ) ) {
631 return;
632 }
633
634 $suggested_module = $settings['suggested_products_module'] ?? 'bulk_discounts';
635
636 switch ( $suggested_module ) {
637 case 'bulk_discounts':
638 $this->print_bulk_discounts( $product );
639 break;
640
641 case 'buy_x_get_y':
642 $this->print_buy_x_get_y( $product );
643 break;
644
645 case 'frequently_bought_together':
646 $this->print_frequently_bought_together( $product );
647 break;
648 }
649 }
650
651 /**
652 * Prints the bulk discounts for the specified product.
653 *
654 * @param $product
655 *
656 * @return void
657 */
658 public function print_bulk_discounts( $product ) {
659 if ( ! merchant_is_pro_active() || ! Merchant_Modules::is_module_active( Merchant_Volume_Discounts::MODULE_ID ) ) {
660 return;
661 }
662
663 $product_id = $product->get_id();
664 $discount_tiers = Merchant_Pro_Volume_Discounts::availabe_offers( $product_id );
665
666 if ( ! empty( $discount_tiers ) ) {
667 merchant_get_template_part(
668 Merchant_Volume_Discounts::MODULE_TEMPLATES_PATH,
669 'single-product',
670 array(
671 'settings' => Merchant_Admin_Options::get_all( Merchant_Volume_Discounts::MODULE_ID ),
672 'product' => $product,
673 'discount_tiers' => $discount_tiers,
674 'product_price' => $product->get_price(),
675 'in_cart' => Merchant_Pro_Volume_Discounts::is_in_cart( $product_id ),
676 'product_cart_quantity' => Merchant_Pro_Volume_Discounts::get_product_cart_quantity( $product_id ),
677 'product_id' => $product_id,
678 )
679 );
680 }
681 }
682
683 /**
684 * Prints the Buy X Get Y offers for the specified product.
685 *
686 * @param $product
687 *
688 * @return void
689 */
690 public function print_buy_x_get_y( $product ) {
691 if ( ! merchant_is_pro_active() || ! Merchant_Modules::is_module_active( Merchant_Buy_X_Get_Y::MODULE_ID ) ) {
692 return;
693 }
694
695 $product_id = $product->get_id();
696 $offers = Merchant_Pro_Buy_X_Get_Y::availabe_offers( $product_id );
697
698 if ( ! empty( $offers ) ) {
699 merchant_get_template_part(
700 Merchant_Buy_X_Get_Y::MODULE_TEMPLATES,
701 'single-product',
702 array(
703 'offers' => $offers,
704 'nonce' => wp_create_nonce( 'merchant_bogo_add_to_cart' ),
705 'settings' => Merchant_Admin_Options::get_all( Merchant_Buy_X_Get_Y::MODULE_ID ),
706 'product' => $product_id,
707 )
708 );
709 }
710 }
711
712 /**
713 * Prints the frequently bought together bundles for the specified product.
714 *
715 * @param $product
716 *
717 * @return void
718 */
719 public function print_frequently_bought_together( $product ) {
720 if ( ! merchant_is_pro_active() || ! Merchant_Modules::is_module_active( Merchant_Frequently_Bought_Together::MODULE_ID ) ) {
721 return;
722 }
723
724 $post_id = $product->get_id();
725 $bundle_data = Merchant_Pro_Frequently_Bought_Together::availabe_offers( $post_id, Merchant_Pro_Frequently_Bought_Together::bundles() );
726
727 if ( ! empty( $bundle_data ) ) {
728 $bundles[ $post_id ] = Merchant_Pro_Frequently_Bought_Together::map_bundles( $bundle_data );
729 }
730
731 if ( ! empty( $bundles ) ) {
732 merchant_get_template_part(
733 Merchant_Frequently_Bought_Together::MODULE_TEMPLATES_PATH,
734 'single-product',
735 array(
736 'bundles' => $bundles,
737 'nonce' => wp_create_nonce( Merchant_Pro_Frequently_Bought_Together::AJAX_NONCE_ACTION ),
738 'settings' => Merchant_Admin_Options::get_all( Merchant_Frequently_Bought_Together::MODULE_ID ),
739 )
740 );
741 }
742 }
743
744 /**
745 * Custom CSS.
746 *
747 * @return string
748 */
749 public function get_module_custom_css() {
750 $css = '';
751
752 // Button Icon Color.
753 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'icon-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-icon-color' );
754
755 // Button Icon Color (hover).
756 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'icon-hover-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-icon-color-hover' );
757
758 // Button Text Color.
759 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'text-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-text-color' );
760
761 // Button Text Color (hover).
762 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'text-hover-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-text-color-hover' );
763
764 // Button Border Color.
765 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'border-color', '#212121', '.merchant-quick-view-button', '--mrc-qv-button-border-color' );
766
767 // Button Border Color (hover).
768 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'border-hover-color', '#414141', '.merchant-quick-view-button', '--mrc-qv-button-border-color-hover' );
769
770 // Button Background Color.
771 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'background-color', '#212121', '.merchant-quick-view-button', '--mrc-qv-button-bg-color' );
772
773 // Button Background Color (hover).
774 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'background-hover-color', '#414141', '.merchant-quick-view-button', '--mrc-qv-button-bg-color-hover' );
775
776 // Button Position Top.
777 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'button-position-top', '50', '.merchant-quick-view-button', '--mrc-qv-button-position-top', '%' );
778
779 // Button Position Left.
780 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'button-position-left', '50', '.merchant-quick-view-button', '--mrc-qv-button-position-left', '%' );
781
782 // Modal Width.
783 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'modal_width', 1000, '.merchant-quick-view-modal', '--mrc-qv-modal-width', 'px' );
784
785 // Modal Height.
786 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'modal_height', 500, '.merchant-quick-view-modal', '--mrc-qv-modal-height', 'px' );
787
788 // Sale Price Color.
789 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'sale-price-color', '#212121', '.merchant-quick-view-modal', '--mrc-qv-modal-sale-price-color' );
790
791 // Regular Price Color.
792 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'regular-price-color', '#414141', '.merchant-quick-view-modal', '--mrc-qv-modal-regular-price-color' );
793
794 return $css;
795 }
796
797 /**
798 * Admin custom CSS.
799 *
800 * @param string $css The custom CSS.
801 * @return string $css The custom CSS.
802 */
803 public function admin_custom_css( $css ) {
804 $css .= $this->get_module_custom_css();
805
806 return $css;
807 }
808
809 /**
810 * Frontend custom CSS.
811 *
812 * @param string $css The custom CSS.
813 * @return string $css The custom CSS.
814 */
815 public function frontend_custom_css( $css ) {
816 $css .= $this->get_module_custom_css();
817
818 return $css;
819 }
820 }
821
822 // Initialize the module.
823 add_action( 'init', function() {
824 Merchant_Quick_View::get_instance();
825 } );
826