PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.5.2
ShopBuilder – WooCommerce Builder For Elementor v2.5.2
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
shopbuilder / app / Modules / QuickView / QuickViewFrontEnd.php

QuickViewFrontEnd.php in ShopBuilder – WooCommerce Builder For Elementor 2.5.2, at app/Modules/QuickView/QuickViewFrontEnd.php

362 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace RadiusTheme\SB\Modules\QuickView;
4
5 use RadiusTheme\SB\Helpers\Fns;
6 use RadiusTheme\SB\Traits\SingletonTrait;
7 use WC_Product;
8
9 // Do not allow directly accessing this file.
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit( 'This script cannot be accessed directly.' );
12 }
13
14 class QuickViewFrontEnd {
15 use SingletonTrait;
16
17 public function __construct() {
18 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue' ] );
19
20 // Gallery Plugin Support rtwpvg_disable_enqueue_scripts.
21 add_filter( 'rtwpvg_disable_enqueue_scripts', '__return_false', 11 );
22
23 // Template.
24
25 add_action( 'rtsb/modules/quick_view/frontend/display', [ $this, 'button_hook' ] );
26 // Add do_action( 'rtsb/modules/quick_view/frontend/display' ); for display anywhere.
27
28 add_action( 'rtsb/modules/quick_view/print_button', [ $this, 'print_button' ] );
29
30 // Load action for product template.
31 $this->quick_view_action_template();
32
33 // ShortCode.
34 add_shortcode( 'rtsb_quick_view_button', [ $this, 'button_shortcode' ] );
35
36 // Quick view AJAX.
37 add_action( 'wp_ajax_rtsb_load_product_quick_view', [ $this, 'product_quick_view_ajax' ] );
38
39 add_action( 'wp_ajax_nopriv_rtsb_load_product_quick_view', [ $this, 'product_quick_view_ajax' ] );
40
41 $this->attach_button();
42 }
43
44
45 /**
46 * Load wc action for quick view product template
47 *
48 * @access public
49 * @return void
50 * @since 1.0.0
51 */
52 public function quick_view_action_template() {
53 wp_enqueue_style( 'elementor-frontend' );
54 // Image.
55 add_action( 'rtsb/wcqv/product/image', 'woocommerce_show_product_sale_flash', 10 );
56 add_action( 'rtsb/wcqv/product/image', 'woocommerce_show_product_images', 20 );
57
58 // Summary.
59 add_action( 'rtsb/wcqv/product/summary', 'woocommerce_template_single_title', 5 );
60 add_action( 'rtsb/wcqv/product/summary', 'woocommerce_template_single_rating', 10 );
61 add_action( 'rtsb/wcqv/product/summary', 'woocommerce_template_single_price', 15 );
62 add_action( 'rtsb/wcqv/product/summary', 'woocommerce_template_single_excerpt', 20 );
63 add_action( 'rtsb/wcqv/product/summary', 'woocommerce_template_single_add_to_cart', 25 );
64 add_action( 'rtsb/wcqv/product/summary', 'woocommerce_template_single_meta', 30 );
65 }
66
67 public function product_quick_view_ajax() {
68 $product_id = isset( $_REQUEST['product_id'] ) ? absint( $_REQUEST['product_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
69
70 if ( empty( $product_id ) || 'publish' !== get_post_status( $product_id ) ) {
71 wp_send_json_error( esc_html__( 'Product Id not found', 'shopbuilder' ) );
72 }
73
74 global $sitepress;
75
76 $lang = isset( $_REQUEST['lang'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['lang'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
77 if ( defined( 'ICL_LANGUAGE_CODE' ) && $lang && isset( $sitepress ) ) {
78 $sitepress->switch_lang( $lang, true );
79 }
80
81 // Set the main wp query for the product.
82 wp( 'p=' . $product_id . '&post_type=product' );
83
84 // Remove product thumbnails gallery.
85 if ( defined( 'RTWPVG_VERSION' ) ) {
86 remove_action( 'woocommerce_product_thumbnails', 'woocommerce_show_product_thumbnails', 20 );
87 }
88 if ( ! defined( 'RTWPVG_VERSION' ) ) {
89 // add_action( 'woocommerce_product_thumbnails', [ $this, 'woocommerce_product_thumbnails_before' ], 1 );
90 // add_action( 'woocommerce_product_thumbnails', [ $this, 'woocommerce_product_thumbnails_after' ], 25 );
91 }
92
93 ob_start();
94 Fns::load_template( 'quick-view/content' );
95 $html = ob_get_contents(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
96 ob_end_clean();
97
98 wp_send_json_success( [ 'html' => $html ] );
99 }
100
101 /**
102 * Add the "Add to Wishlist" button. Needed to use in wp_head hook.
103 *
104 * @return void
105 * @since 1.0.0
106 */
107 public function attach_button() {
108
109 $positions = apply_filters(
110 'rtsb/module/quick_view/loop_btn_position',
111 [
112
113 'before_add_to_cart' => [
114 'hook' => 'woocommerce_after_shop_loop_item',
115 'priority' => 7,
116 ],
117 'after_add_to_cart' => [
118 'hook' => 'woocommerce_after_shop_loop_item',
119 'priority' => 15,
120 ],
121 'custom' => [
122 'hook' => Fns::get_option( 'modules', 'quick_view', 'loop_custom_hook_name', '' ),
123 'priority' => Fns::get_option( 'modules', 'quick_view', 'loop_custom_hook_priority', '' ),
124 ],
125 ]
126 );
127
128 // Add the link "Add to wishlist" in the loop.
129
130 $loop_btn_position = Fns::get_option( 'modules', 'quick_view', 'loop_btn_position', 'after_add_to_cart' );
131
132 if ( 'shortcode' !== $loop_btn_position && isset( $positions[ $loop_btn_position ]['hook'] ) ) {
133 add_action(
134 $positions[ $loop_btn_position ]['hook'],
135 [
136 $this,
137 'button_hook',
138 ],
139 isset( $positions[ $loop_btn_position ]['priority'] ) ? $positions[ $loop_btn_position ]['priority'] : ''
140 );
141 }
142 // TODO:: Maybe this hooks is not working. Need to Check gutenberg compatibility.
143 // Add the link "Quick view" for Gutenberg blocks.
144 add_filter( 'woocommerce_blocks_product_grid_item_html', [ $this, 'add_button_for_block' ], 10, 3 );
145 }
146
147 /**
148 * Print "Add to compare" button
149 *
150 * @return void
151 */
152 public function woocommerce_product_thumbnails_before() {
153 ?>
154 <div class="rtsb-gallery-images-wrapper">
155 <?php
156 }
157 /**
158 * Print "Add to compare" button
159 *
160 * @return void
161 */
162 public function woocommerce_product_thumbnails_after() {
163
164 ?>
165 </div>
166 <?php
167 }
168
169 /**
170 * Print "Add to compare" button
171 *
172 * @return void
173 */
174 public function button_hook() {
175 if ( ! apply_filters( 'rtsb/module/quick_view/show_button', true ) ) {
176 return;
177 }
178 global $product;
179 if ( $product instanceof WC_Product ) {
180 do_action( 'rtsb/modules/quick_view/print_button', $product->get_id() );
181 }
182 }
183
184
185 /**
186 * @return string|void
187 */
188 public function print_button( $product_id = 0 ) {
189 global $product;
190
191 if ( ! $product instanceof WC_Product && $product_id ) {
192 $product = wc_get_product( $product_id );
193 }
194
195 // if ( ! $current_product instanceof WC_Product ) {
196 // return '';
197 // }
198
199 $classes = []; // button class.
200 $button_text = Fns::get_option( 'modules', 'quick_view', 'button_text', esc_html__( 'Quick View', 'shopbuilder' ) );
201
202 $icon_html = '<i class="rtsb-icon rtsb-icon-eye"></i>';
203 // get product type.
204 $product_type = $product->get_type();
205 $params = [
206 'classes' => $classes,
207 'product_id' => $product->get_id(),
208 'product_type' => $product_type,
209 'button_text' => $button_text,
210 'has_button_text' => ! empty( Fns::get_option( 'modules', 'quick_view', 'button_text', '' ) ),
211 'left_text' => apply_filters( 'rtsb/module/quick_view/button_left_text', '' ),
212 'right_text' => apply_filters( 'rtsb/module/quick_view/button_right_text', '' ),
213 ];
214 // let third party developer filter options.
215 $atts = apply_filters( 'rtsb/module/quick_view/button_params', $params );
216 // set fragment options.
217 $atts['icon_html'] = apply_filters( 'rtsb/module/quick_view/icon_html', $icon_html, $atts );
218
219 Fns::load_template( 'quick-view/button', $atts );
220 }
221
222
223 /**
224 * Wishlist button Shortcode callable function
225 *
226 * @param array $atts
227 * @param string $content
228 *
229 * @return string [HTML]
230 */
231 public function button_shortcode( $atts, $content = '' ) {
232 global $product;
233 if ( ! $product instanceof WC_Product ) {
234 return '';
235 }
236 ob_start();
237
238 do_action( 'rtsb/modules/quick_view/print_button', $product->get_id() );
239
240 return ob_get_clean();
241 }
242
243 public function enqueue() {
244
245 wp_enqueue_style( 'elementor-icons-fa-regular' );
246
247 wp_enqueue_style( 'elementor-icons-fa-solid' );
248 wp_enqueue_style( 'elementor-icons-shared-0' );
249 // wp_enqueue_style( 'elementor-frontend' );
250
251 if ( ! class_exists( 'WooProductVariationGallery' ) && current_theme_supports( 'wc-product-gallery-slider' ) ) {
252 wp_enqueue_script( 'flexslider' );
253 }
254
255 wp_enqueue_script( 'wc-add-to-cart-variation' );
256 if ( version_compare( WC()->version, '3.0.0', '>=' ) ) {
257 if ( current_theme_supports( 'wc-product-gallery-zoom' ) ) {
258 wp_enqueue_script( 'zoom' );
259 }
260 if ( current_theme_supports( 'wc-product-gallery-lightbox' ) ) {
261 wp_enqueue_script( 'photoswipe-ui-default' );
262 wp_enqueue_style( 'photoswipe-default-skin' );
263 if ( has_action( 'wp_footer', 'woocommerce_photoswipe' ) === false ) {
264 add_action( 'wp_footer', 'woocommerce_photoswipe', 15 );
265 }
266 }
267 wp_enqueue_script( 'wc-single-product' );
268 }
269
270 wp_register_style( 'rtsb-modules', rtsb()->get_assets_uri( 'modules/modules.css' ), [], RTSB_VERSION );
271 wp_register_script(
272 'rtsb-quick-view',
273 rtsb()->get_assets_uri( 'modules/quick-view.js' ),
274 [
275 'jquery',
276 'rtsb-public',
277 ],
278 RTSB_VERSION,
279 true
280 );
281 wp_enqueue_style( 'rtsb-modules' );
282 wp_enqueue_script( 'rtsb-quick-view' );
283
284 // Allow user to load custom style and scripts!
285 do_action( 'rtsb/modules/quick_view/custom_scripts' );
286
287 $params = apply_filters(
288 'rtsb/module/quick_view/js_params',
289 [
290 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ),
291 'lang' => defined( 'ICL_LANGUAGE_CODE' ) ? ICL_LANGUAGE_CODE : '',
292 'isLoggedIn' => is_user_logged_in(),
293 ]
294 );
295
296 wp_localize_script( 'rtsb-quick-view', 'rtsbQvParams', $params );
297 }
298
299
300 /**
301 * Add ATW button to Products block item
302 *
303 * @param string $item_html HTML of the single block item.
304 * @param array $data Data used to render the item.
305 * @param WC_Product $product Current product.
306 *
307 * @return string Filtered HTML.
308 */
309 public function add_button_for_block( $item_html, $data, $product ) {
310 // Add the link "Add to wishlist" in the loop.
311 $shop_btn_position = Fns::get_option( 'modules', 'quick_view', 'loop_btn_position', 'after_add_to_cart' );
312 ob_start();
313 $this->print_button( $product->get_id() );
314 $button = ob_get_clean();
315 $parts = [];
316
317 preg_match( '/(<li class=".*?">)[\S|\s]*?(<a .*?>[\S|\s]*?<\/a>)([\S|\s]*?)(<\/li>)/', $item_html, $parts );
318
319 if ( ! $parts || count( $parts ) < 5 ) {
320 return $item_html;
321 }
322
323 // removes first match (entire match).
324 array_shift( $parts );
325
326 // removes empty parts.
327 $parts = array_filter( $parts );
328
329 // searches for index to cut parts array.
330 switch ( $shop_btn_position ) {
331
332 case 'before_add_to_cart':
333 $index = 2;
334 break;
335 case 'after_add_to_cart':
336 $index = 3;
337 break;
338 default:
339 $index = 0;
340 break;
341 }
342
343 // if index is found, stitch button in correct position.
344 if ( $index ) {
345 $first_set = array_slice( $parts, 0, $index );
346 $second_set = array_slice( $parts, $index );
347
348 $parts = array_merge(
349 $first_set,
350 (array) $button,
351 $second_set
352 );
353
354 // replace li classes.
355 $parts[0] = preg_replace( '/class="(.*)"/', 'class="$1 rtsb-quick-view-btn-' . $shop_btn_position . '"', $parts[0] );
356 }
357
358 // join all parts together and return item.
359 return implode( '', $parts );
360 }
361 }
362