PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 1.6
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v1.6
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.6, at inc/modules/quick-view/class-quick-view.php

578 lines 19.7 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 /**
32 * Constructor.
33 *
34 */
35 public function __construct() {
36
37 // Module id.
38 $this->module_id = self::MODULE_ID;
39
40 // WooCommerce only.
41 $this->wc_only = true;
42
43 // Parent construct.
44 parent::__construct();
45
46 // Module section.
47 $this->module_section = 'convert-more';
48
49 // Module default settings.
50 $this->module_default_settings = array(
51 'button_type' => 'text',
52 'button_text' => __( 'Quick View', 'merchant' ),
53 'button_icon' => 'eye',
54 'button_position' => 'overlay',
55 'button-position-top' => 50,
56 'button-position-left' => 50,
57 'zoom_effect' => 1,
58 'show_quantity' => 1,
59 'place_product_description' => 'top',
60 'description_style' => 'short',
61 'place_product_image' => 'thumbs-at-left'
62 );
63
64 // Mount preview url.
65 $preview_url = site_url( '/' );
66
67 if ( function_exists( 'wc_get_page_id' ) ) {
68 $preview_url = get_permalink( wc_get_page_id( 'shop' ) );
69 }
70
71 // Module data.
72 $this->module_data = Merchant_Admin_Modules::$modules_data[ self::MODULE_ID ];
73 $this->module_data[ 'preview_url' ] = $preview_url;
74
75 // Module options path.
76 $this->module_options_path = MERCHANT_DIR . 'inc/modules/' . self::MODULE_ID . '/admin/options.php';
77
78 // Is module preview page.
79 if ( is_admin() && parent::is_module_settings_page() ) {
80 self::$is_module_preview = true;
81
82 // Enqueue admin styles.
83 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_css' ) );
84
85 // Admin preview box.
86 add_filter( 'merchant_module_preview', array( $this, 'render_admin_preview' ), 10, 2 );
87
88 // Custom CSS.
89 // The custom CSS should be added here as well due to ensure preview box works properly.
90 add_filter( 'merchant_custom_css', array( $this, 'admin_custom_css' ) );
91
92 }
93
94 if ( ! Merchant_Modules::is_module_active( self::MODULE_ID ) ) {
95 return;
96 }
97
98 // Return early if it's on admin but not in the respective module settings page.
99 if ( is_admin() && ! parent::is_module_settings_page() && ! defined( 'DOING_AJAX' ) ) {
100 return;
101 }
102
103 // Enqueue styles.
104 add_action( 'merchant_enqueue_before_main_css_js', array( $this, 'enqueue_css' ) );
105
106 // Enqueue scripts.
107 add_action( 'merchant_enqueue_after_main_css_js', array( $this, 'enqueue_scripts' ) );
108
109 // Localize script.
110 add_filter( 'merchant_localize_script', array( $this, 'localize_script' ) );
111
112 // Handle Botiga theme scripts for compatibility.
113 if ( defined( 'BOTIGA_PRO_URI' ) && defined( 'BOTIGA_PRO_VERSION' ) ) {
114 add_action( 'wp_enqueue_scripts', array( $this, 'modal_compatibility_with_botiga_theme' ) );
115 }
116
117 // Modal content ajax callback.
118 add_action( 'wp_ajax_merchant_quick_view_content', array( $this, 'modal_content_ajax_callback' ) );
119 add_action( 'wp_ajax_nopriv_merchant_quick_view_content', array( $this, 'modal_content_ajax_callback' ) );
120
121 // Button Position.
122 $button_position = Merchant_Admin_Options::get( self::MODULE_ID, 'button_position', 'overlay' );
123
124 if ( 'before' === $button_position ) {
125 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'quick_view_button' ), 5 );
126 } elseif ( 'after' === $button_position ) {
127 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'quick_view_button' ), 15 );
128 } elseif ( 'overlay' === $button_position ) {
129 if ( merchant_is_kadence_active() ) {
130 add_filter( 'kadence_archive_content_wrap_start', array( $this, 'add_quick_view_button' ) );
131 } else {
132 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'quick_view_button' ), 15 );
133 }
134 }
135
136 // Inject quick view modal output on footer.
137 add_action( 'wp_footer', array( $this, 'modal_output' ) );
138
139 // Custom CSS.
140 add_filter( 'merchant_custom_css', array( $this, 'frontend_custom_css' ) );
141
142 }
143
144 /**
145 * Concatenate the quick view button with the content start wrap.
146 *
147 * @return string
148 */
149 public function add_quick_view_button() {
150 return $this->quick_view_button() . '<div class="product-details content-bg entry-content-wrap">';
151 }
152
153 /**
154 * Admin enqueue CSS.
155 *
156 * @return void
157 */
158 public function admin_enqueue_css() {
159 $page = ( ! empty( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
160 $module = ( ! empty( $_GET['module'] ) ) ? sanitize_text_field( wp_unslash( $_GET['module'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
161
162 if ( 'merchant' === $page && self::MODULE_ID === $module ) {
163 wp_enqueue_style( 'merchant-' . self::MODULE_ID, MERCHANT_URI . 'assets/css/modules/' . self::MODULE_ID . '/quick-view.min.css', [], MERCHANT_VERSION );
164 wp_enqueue_style( 'merchant-admin-' . self::MODULE_ID, MERCHANT_URI . 'assets/css/modules/' . self::MODULE_ID . '/admin/preview.min.css', array(), MERCHANT_VERSION );
165 }
166 }
167
168 /**
169 * Enqueue CSS.
170 *
171 * @return void
172 */
173 public function enqueue_css() {
174
175 // Specific module styles.
176 wp_enqueue_style( 'merchant-' . self::MODULE_ID, MERCHANT_URI . 'assets/css/modules/' . self::MODULE_ID . '/quick-view.min.css', array(), MERCHANT_VERSION );
177 }
178
179 /**
180 * Enqueue scripts.
181 *
182 * @return void
183 */
184 public function enqueue_scripts() {
185 wp_enqueue_script( 'zoom' );
186 wp_enqueue_script( 'flexslider' );
187 wp_enqueue_script( 'wc-single-product' );
188 wp_enqueue_script( 'wc-add-to-cart-variation' );
189
190 // Register and enqueue the main module script.
191 wp_enqueue_script( 'merchant-' . self::MODULE_ID, MERCHANT_URI . 'assets/js/modules/' . self::MODULE_ID . '/quick-view.min.js', array(), MERCHANT_VERSION, true );
192 }
193
194 /**
195 * Localize script with module settings.
196 *
197 * @param array $setting The merchant global object setting parameter.
198 * @return array $setting The merchant global object setting parameter.
199 */
200 public function localize_script( $setting ) {
201 $module_settings = $this->get_module_settings();
202
203 $setting[ 'quick_view' ] = true;
204 $setting[ 'quick_view_zoom' ] = $module_settings[ 'zoom_effect' ];
205
206 return $setting;
207 }
208
209 /**
210 * Enqueue botiga theme scripts.
211 *
212 * @return void
213 */
214 public function modal_compatibility_with_botiga_theme() {
215 if ( ! wp_script_is( 'botiga-product-swatch' ) ) {
216 wp_enqueue_script( 'botiga-product-swatch', BOTIGA_PRO_URI . 'assets/js/botiga-product-swatch.min.js', array(), BOTIGA_PRO_VERSION, true );
217 }
218
219 if ( ! wp_script_is( 'botiga-checkout-quantity-input' ) ) {
220 wp_enqueue_script( 'botiga-checkout-quantity-input', BOTIGA_PRO_URI . 'assets/js/botiga-checkout-quantity-input.min.js', array( 'jquery' ), BOTIGA_PRO_VERSION, true );
221 }
222 }
223
224 /**
225 * Render admin preview
226 *
227 * @param Merchant_Admin_Preview $preview
228 * @param string $module
229 *
230 * @return Merchant_Admin_Preview
231 */
232 public function render_admin_preview( $preview, $module ) {
233 if ( self::MODULE_ID === $module ) {
234 ob_start();
235 self::admin_preview_content();
236 $content = ob_get_clean();
237
238 // HTML.
239 $preview->set_html( $content );
240
241 // Button Type.
242 $preview->set_class( 'button_type', '.merchant-quick-view-button', array( 'icon', 'icon-text', 'text' ) );
243
244 // Button Text.
245 $preview->set_text( 'button_text', '.button-text' );
246
247 // Button Icon.
248 $preview->set_svg_icon( 'button_icon', '.quick-view-icon' );
249
250 // Button Position.
251 $preview->set_class( 'button_position', '.merchant-quick-view-preview', array( 'before', 'after', 'overlay' ) );
252
253 }
254
255 return $preview;
256 }
257
258 /**
259 * Admin preview content.
260 *
261 * @return void
262 */
263 public function admin_preview_content() {
264 $settings = $this->get_module_settings();
265
266 ?>
267
268 <div class="merchant-quick-view-preview <?php echo esc_attr( $settings[ 'button_position' ] ); ?>">
269 <div class="image-wrapper">
270 <div class="button-position button-position-overlay">
271 <?php $this->admin_preview_quick_view_button(); ?>
272 </div>
273 </div>
274 <h3><?php echo esc_html__( 'Product Title', 'merchant' ); ?></h3>
275 <p><?php echo esc_html__( 'The product description normally is displayed here.', 'merchant' ); ?></p>
276 <div class="button-position button-position-before">
277 <?php $this->admin_preview_quick_view_button(); ?>
278 </div>
279 <div>
280 <a href="#" class="add_to_cart_button"><?php echo esc_html__( 'Add To Cart', 'merchant' ); ?></a>
281 </div>
282 <div class="button-position button-position-after">
283 <?php $this->admin_preview_quick_view_button(); ?>
284 </div>
285
286 </div>
287
288 <?php
289 }
290
291 /**
292 * Admin preview quick view button.
293 *
294 * @return void
295 */
296 public function admin_preview_quick_view_button() {
297 $settings = $this->get_module_settings();
298
299 ?>
300
301 <a href="#" class="merchant-quick-view-button <?php echo esc_attr( $settings[ 'button_type' ] ); ?>">
302 <span class="button-type button-type-icon">
303 <span class="quick-view-icon">
304 <?php echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $settings[ 'button_icon' ] ), merchant_kses_allowed_tags( [], false ) ); ?>
305 </span>
306 </span>
307 <span class="button-type button-type-icon-text">
308 <span class="quick-view-icon">
309 <?php echo wp_kses( Merchant_SVG_Icons::get_svg_icon( $settings[ 'button_icon' ] ), merchant_kses_allowed_tags( [], false ) ); ?>
310 </span>
311 <span class="button-text"><?php echo esc_html( $settings[ 'button_text' ] ); ?></span>
312 </span>
313 <span class="button-type button-type-text">
314 <span class="button-text"><?php echo esc_html( $settings[ 'button_text' ] ); ?></span>
315 </span>
316 </a>
317
318 <?php
319 }
320
321 /**
322 * Modal content ajax callback.
323 * TODO: Render the output through templates files.
324 *
325 * @return void
326 */
327 public function modal_content_ajax_callback() {
328 check_ajax_referer( 'merchant-nonce', 'nonce' );
329
330 if ( ! isset( $_POST['product_id'] ) || ! function_exists( 'wc_get_product' ) ) {
331 wp_send_json_error();
332 }
333
334 $args = array(
335 'product_id' => absint( $_POST['product_id'] )
336 );
337
338 global $product;
339
340 $settings = $this->get_module_settings();
341 $product = wc_get_product( $args['product_id'] );
342
343 if ( is_wp_error( $product ) || empty( $product ) ) {
344 wp_send_json_error();
345 }
346
347 $product_id = $product->get_id();
348 $hide_quantity = ( empty( $settings[ 'show_quantity' ] ) ) ? 'merchant-hide-quantity' : '';
349
350 ob_start();
351
352 ?>
353
354 <div id="product-<?php echo absint( $product_id ); ?>" <?php wc_product_class( '', $product ); ?>>
355
356 <div class="merchant-quick-view-row">
357
358 <div class="merchant-quick-view-column">
359 <div class="merchant-quick-view-product-gallery">
360 <?php woocommerce_show_product_images(); ?>
361 </div>
362 </div>
363
364 <div class="merchant-quick-view-column">
365
366 <div class="merchant-quick-view-summary product-gallery-summary">
367
368 <div class="merchant-quick-view-product-title">
369 <h2 class="product_title entry-title"><?php echo esc_html( $product->get_title() ); ?></h2>
370 </div>
371 <?php if ( 0 != $product->get_average_rating() ) : ?>
372 <div class="merchant-quick-view-product-rating">
373 <div class="woocommerce-product-rating">
374 <?php echo wp_kses( wc_get_rating_html( $product->get_average_rating() ), merchant_kses_allowed_tags() ); ?>
375 </div>
376 </div>
377 <?php endif; ?>
378 <div class="merchant-quick-view-product-price">
379 <div class="price"><?php echo wp_kses( $product->get_price_html(), merchant_kses_allowed_tags() ); ?></div>
380 </div>
381 <?php if ( 'top' === $settings[ 'place_product_description' ] ) : ?>
382 <?php if ( 'full' === $settings[ 'description_style' ] ) : ?>
383 <div class="merchant-quick-view-product-excerpt">
384 <?php echo wp_kses_post( $product->get_description() ); ?>
385 </div>
386 <?php else : ?>
387 <div class="merchant-quick-view-product-excerpt">
388 <p><?php echo wp_kses_post( $product->get_short_description() ); ?></p>
389 </div>
390 <?php endif; ?>
391 <?php endif; ?>
392 <div class="merchant-quick-view-product-add-to-cart <?php echo esc_attr( $hide_quantity ); ?>">
393 <?php woocommerce_template_single_add_to_cart(); ?>
394 </div>
395 <?php if ( 'bottom' === $settings[ 'place_product_description' ] ) : ?>
396 <?php if ( 'full' === $settings[ 'description_style' ] ) : ?>
397 <div class="merchant-quick-view-product-excerpt">
398 <?php echo wp_kses_post( $product->get_description() ); ?>
399 </div>
400 <?php else : ?>
401 <div class="merchant-quick-view-product-excerpt">
402 <p><?php echo wp_kses_post( $product->get_short_description() ); ?></p>
403 </div>
404 <?php endif; ?>
405 <?php endif; ?>
406 <div class="merchant-quick-view-product-meta">
407 <?php woocommerce_template_single_meta(); ?>
408 </div>
409
410 <?php
411 /**
412 * Hook 'merchant_quick_view_after_product_excerpt'
413 *
414 * @since 1.0.0
415 */
416 do_action( 'merchant_quick_view_after_product_meta' );
417 ?>
418
419 </div>
420
421 </div>
422
423 </div>
424
425 </div>
426
427 <?php
428
429 $content = ob_get_contents();
430
431 ob_get_clean();
432
433 wp_send_json_success( $content );
434
435 }
436
437 /**
438 * Modal output.
439 * TODO: Render the output through templates files.
440 *
441 * @return void
442 */
443 public function modal_output() {
444 $settings = $this->get_module_settings();
445
446 ?>
447 <div class="single-product merchant-quick-view-modal merchant-quick-view-<?php echo esc_attr( $settings[ 'place_product_image' ] ); ?>">
448 <div class="merchant-quick-view-overlay"></div>
449 <div class="merchant-quick-view-loader">
450 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
451 <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" />
452 <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" />
453 </svg>
454 </div>
455 <div class="merchant-quick-view-inner">
456 <a href="#" class="merchant-quick-view-close-button" title="<?php echo esc_attr__( 'Close quick view modal', 'merchant' ); ?>">
457 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
458 <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"/>
459 </svg>
460 </a>
461 <div class="merchant-quick-view-content"></div>
462 </div>
463 </div>
464 <?php
465 }
466
467 /**
468 * Quick view button.
469 *
470 * @return void
471 */
472 public function quick_view_button() {
473 global $product;
474
475 $settings = $this->get_module_settings();
476 $product_id = $product->get_id();
477
478 $button_text_html = '';
479 $button_icon_html = '';
480
481 if ( 'icon' === $settings[ 'button_type' ] || 'icon-text' === $settings[ 'button_type' ] ) {
482 $button_icon_html = Merchant_SVG_Icons::get_svg_icon( $settings[ 'button_icon' ] );
483 }
484
485 if ( 'text' === $settings[ 'button_type' ] || 'icon-text' === $settings[ 'button_type' ] ) {
486 $button_text_html = '<span>' . $settings[ 'button_text' ] . '</span>';
487 }
488
489 ?>
490 <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( [], false ) ) . wp_kses_post( $button_text_html ); ?></a>
491 <?php
492
493 }
494
495 /**
496 * Custom CSS.
497 *
498 * @return string
499 */
500 public function get_module_custom_css() {
501 $css = '';
502
503 // Button Icon Color.
504 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'icon-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-icon-color' );
505
506 // Button Icon Color (hover).
507 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'icon-hover-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-icon-hover-color' );
508
509 // Button Text Color.
510 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'text-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-color' );
511
512 // Button Text Color (hover).
513 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'text-hover-color', '#ffffff', '.merchant-quick-view-button', '--mrc-qv-button-color-hover' );
514
515 // Button Border Color.
516 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'border-color', '#212121', '.merchant-quick-view-button', '--mrc-qv-button-border-color' );
517
518 // Button Border Color (hover).
519 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'border-hover-color', '#414141', '.merchant-quick-view-button', '--mrc-qv-button-border-color-hover' );
520
521 // Button Background Color.
522 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'background-color', '#212121', '.merchant-quick-view-button', '--mrc-qv-button-bg-color' );
523
524 // Button Background Color (hover).
525 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'background-hover-color', '#414141', '.merchant-quick-view-button', '--mrc-qv-button-bg-color-hover' );
526
527 // Button Position Top.
528 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'button-position-top', '50', '.merchant-quick-view-button', '--mrc-qv-button-position-top', '%' );
529
530 // Button Position Left.
531 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'button-position-left', '50', '.merchant-quick-view-button', '--mrc-qv-button-position-left', '%' );
532
533 // Modal Width.
534 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'modal_width', 1000, '.merchant-quick-view-modal', '--mrc-qv-modal-width', 'px' );
535
536 // Modal Height.
537 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'modal_height', 500, '.merchant-quick-view-modal', '--mrc-qv-modal-height', 'px' );
538
539 // Sale Price Color.
540 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'sale-price-color', '#212121', '.merchant-quick-view-modal', '--mrc-qv-modal-sale-price-color' );
541
542 // Regular Price Color.
543 $css .= Merchant_Custom_CSS::get_variable_css( 'quick-view', 'regular-price-color', '#414141', '.merchant-quick-view-modal', '--mrc-qv-modal-regular-price-color' );
544
545 return $css;
546 }
547
548 /**
549 * Admin custom CSS.
550 *
551 * @param string $css The custom CSS.
552 * @return string $css The custom CSS.
553 */
554 public function admin_custom_css( $css ) {
555 $css .= $this->get_module_custom_css();
556
557 return $css;
558 }
559
560 /**
561 * Frontend custom CSS.
562 *
563 * @param string $css The custom CSS.
564 * @return string $css The custom CSS.
565 */
566 public function frontend_custom_css( $css ) {
567 $css .= $this->get_module_custom_css();
568
569 return $css;
570 }
571
572 }
573
574 // Initialize the module.
575 add_action( 'init', function() {
576 new Merchant_Quick_View();
577 } );
578