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

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