PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.3.0
ShopBuilder – WooCommerce Builder For Elementor v3.3.0
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 / Controllers / Hooks / BuilderHooks.php

BuilderHooks.php in ShopBuilder – WooCommerce Builder For Elementor 3.3.0, at app/Controllers/Hooks/BuilderHooks.php

313 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main initialization class.
4 *
5 * @package RadiusTheme\SB
6 */
7
8 namespace RadiusTheme\SB\Controllers\Hooks;
9
10 defined( 'ABSPATH' ) || exit();
11
12 use RadiusTheme\SB\Helpers\Fns;
13 use RadiusTheme\SB\Helpers\BuilderFns;
14 use RadiusTheme\SB\Helpers\ElementorDataMap;
15 use RadiusTheme\SB\Models\TemplateSettings;
16 use RadiusTheme\SB\Traits\SingletonTrait;
17
18 /**
19 * Builder Frontend.
20 */
21 class BuilderHooks {
22 /**
23 * Builder page id.
24 *
25 * @var integer
26 */
27 private $builder_page_id = 0;
28
29 /**
30 * Page Edit By.
31 *
32 * @var string
33 */
34 private $page_edit_with = '';
35
36 /**
37 * Internal cache.
38 *
39 * @var array
40 */
41 private static $cache = [];
42
43 /**
44 * Singleton.
45 */
46 use SingletonTrait;
47
48 /**
49 * Final constructor.
50 */
51 private function __construct() {
52 // Template Redirect hook run after the global query.
53 add_action( 'template_redirect', [ $this, 'frontend_init' ] );
54 add_filter( 'rtsb/builder/set/current/page/type', [ $this, 'builder_page_type' ] );
55 add_filter( 'body_class', [ $this, 'product_page_body_class' ] );
56 add_action( 'pre_get_posts', [ $this, 'override_archive_posts_per_page' ] );
57 }
58
59 /**
60 * Override posts_per_page for shop/archive pages based on widget setting.
61 *
62 * @param \WP_Query $query The WP_Query instance.
63 *
64 * @return void
65 */
66 public function override_archive_posts_per_page( $query ) {
67 if ( is_admin() || ! $query->is_main_query() ) {
68 return;
69 }
70
71 if ( ! ( is_shop() || is_product_taxonomy() ) ) {
72 return;
73 }
74
75 $type = is_shop() ? 'shop' : 'archive';
76 $option_name = BuilderFns::option_name( $type );
77 $builder_page_id = TemplateSettings::instance()->get_option( $option_name );
78
79 if ( empty( $builder_page_id ) ) {
80 $option_name = BuilderFns::option_name( $type, true );
81 $builder_page_id = TemplateSettings::instance()->get_option( $option_name );
82 }
83
84 // Fallback: use shop template for archive pages when no archive template exists.
85 if ( empty( $builder_page_id ) && 'archive' === $type ) {
86 $option_name = BuilderFns::option_name( 'shop' );
87 $builder_page_id = TemplateSettings::instance()->get_option( $option_name );
88
89 if ( empty( $builder_page_id ) ) {
90 $option_name = BuilderFns::option_name( 'shop', true );
91 $builder_page_id = TemplateSettings::instance()->get_option( $option_name );
92 }
93 }
94
95 if ( empty( $builder_page_id ) ) {
96 return;
97 }
98
99 $per_page = $this->get_archive_widget_per_page( $builder_page_id );
100
101 if ( $per_page ) {
102 $query->set( 'posts_per_page', $per_page );
103 }
104 }
105
106 /**
107 * Get posts_per_page from the ProductsArchive widget in Elementor data.
108 *
109 * @param int $post_id Builder page ID.
110 *
111 * @return int|false The per page value or false if not set.
112 */
113 private function get_archive_widget_per_page( $post_id ) {
114 $cache_key = 'rtsb_archive_per_page_' . $post_id;
115
116 if ( isset( self::$cache[ $cache_key ] ) ) {
117 return self::$cache[ $cache_key ];
118 }
119
120 // Check default layout widget first.
121 $widgets = ElementorDataMap::instance()->get_widget_data( 'rtsb-products-archive', null, $post_id );
122
123 if ( ! empty( $widgets ) ) {
124 $widget = reset( $widgets );
125 $per_page = isset( $widget['settings']['posts_per_page'] ) && '' !== $widget['settings']['posts_per_page']
126 ? absint( $widget['settings']['posts_per_page'] )
127 : false;
128
129 self::$cache[ $cache_key ] = $per_page;
130
131 return $per_page;
132 }
133
134 // Check custom layout widget.
135 $widgets = ElementorDataMap::instance()->get_widget_data( 'rtsb-products-archive-custom', null, $post_id );
136
137 if ( ! empty( $widgets ) ) {
138 $widget = reset( $widgets );
139 $per_page = isset( $widget['settings']['posts_per_page'] ) && '' !== $widget['settings']['posts_per_page']
140 ? absint( $widget['settings']['posts_per_page'] )
141 : false;
142
143 self::$cache[ $cache_key ] = $per_page;
144
145 return $per_page;
146 }
147
148 self::$cache[ $cache_key ] = false;
149
150 return false;
151 }
152
153 /**
154 * Builder page Body class.
155 *
156 * @param array $classes class list.
157 * @return array.
158 */
159 public function product_page_body_class( $classes ) {
160 $classes[] = 'rtsb-shopbuilder-plugin rtsb-shopbuilder-v-' . RTSB_VERSION . ' rtsb_theme_' . rtsb()->current_theme;
161
162 if ( defined( 'RTSBPRO_VERSION' ) ) {
163 $classes[] = 'rtsb-shopbuilder-pro-v-' . RTSBPRO_VERSION;
164 }
165 if ( Fns::is_woocommerce() || BuilderFns::is_builder_preview() ) {
166 $classes[] = 'woocommerce-page';
167 }
168
169 if ( BuilderFns::is_product() ) {
170 $classes[] = 'single-product';
171 }
172
173 if ( BuilderFns::is_shop() ) {
174 $classes[] = 'woocommerce-shop';
175 }
176
177 if ( BuilderFns::is_cart() ) {
178 $classes[] = 'woocommerce-cart';
179 } else {
180 $classes[] = 'woocommerce';
181 }
182
183 if ( BuilderFns::is_checkout() ) {
184 $classes[] = 'woocommerce-checkout ';
185 }
186
187 if ( rtsb()->has_pro() ) {
188 $disable_cart = Fns::is_guest_feature_disabled( 'hide_cart_page', '' );
189 $disable_checkout = Fns::is_guest_feature_disabled( 'hide_checkout_page', '' );
190
191 if ( $disable_cart || $disable_checkout ) {
192 $classes[] = 'rtsb-not-visible';
193 }
194 }
195
196 $hide_notification = Fns::get_option( 'general', 'notification', 'hide_notification', '' );
197
198 if ( 'on' === $hide_notification ) {
199 $classes[] = 'rtsb-notifications-hidden';
200 }
201
202 return $classes;
203 }
204 /**
205 * Undocumented function
206 *
207 * @return void
208 */
209 public function frontend_init() {
210 $this->builder_page_id = BuilderFns::builder_page_id_by_page();
211 $this->page_edit_with = Fns::page_edit_with( $this->builder_page_id );
212 if ( $this->builder_page_id ) {
213 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
214 $this->elementor_frontend();
215 } elseif ( 'gutenberg' === $this->page_edit_with ) {
216 $this->gutenberg_frontend();
217 }
218 }
219 }
220 /**
221 * Appl for gutenberg.
222 *
223 * @return void
224 */
225 public function elementor_frontend() {
226 add_action( 'rtsb/builder/before/header', [ $this, 'el_body_class' ] );
227 add_action( 'rtsb/builder/template/main/content', [ $this, 'elementor_template_main_content' ] );
228 }
229
230 /**
231 * Appl for Elementor.
232 *
233 * @return void
234 */
235 public function gutenberg_frontend() {
236 add_action( 'rtsb/builder/template/main/content', [ $this, 'gutenberg_template_main_content' ] );
237 }
238 /**
239 * Apply For the supported builder page.
240 *
241 * @param string $type string.
242 * @return string
243 */
244 public function builder_page_type( $type ) {
245
246 if ( BuilderFns::is_shop() ) {
247 $type = 'shop';
248 } elseif ( BuilderFns::is_archive() ) {
249 $type = 'archive';
250 } elseif ( BuilderFns::is_product() ) {
251 $type = 'product';
252 } elseif ( BuilderFns::is_checkout() ) {
253 $type = 'checkout';
254 wp_enqueue_script( 'wc-checkout' );
255 } elseif ( BuilderFns::is_cart() ) {
256 $type = 'cart';
257 }
258 wp_enqueue_style( Fns::optimized_handle( 'rtsb-frontend' ) );
259 wp_enqueue_script( Fns::optimized_handle( 'rtsb-public' ) );
260
261 return apply_filters( 'rtsb/builder/set/current/page/type/external', $type );
262 }
263
264 /**
265 * Appl for Elementor.
266 *
267 * @return void
268 */
269 public function el_body_class() {
270 if ( ! class_exists( '\Elementor\Plugin' ) || empty( \Elementor\Plugin::$instance->frontend ) ) {
271 return;
272 }
273
274 $page_template = get_post_meta( $this->builder_page_id, '_wp_page_template', true );
275
276 if ( 'elementor_canvas' === $page_template ) {
277 \Elementor\Plugin::$instance->frontend->add_body_class( 'elementor-template-canvas' );
278 } elseif ( 'elementor_header_footer' === $page_template ) {
279 \Elementor\Plugin::$instance->frontend->add_body_class( 'elementor-template-full-width' );
280 }
281 }
282
283 /**
284 * Apply for Elementor.
285 *
286 * @return void
287 */
288 public function elementor_template_main_content() {
289 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
290 echo BuilderFns::get_builder_content( $this->builder_page_id );
291 }
292 /**
293 * Apply for Gutenberg.
294 *
295 * @return void
296 */
297 public function gutenberg_template_main_content() {
298 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
299 $output = '';
300 $content = get_the_content( null, false, $this->builder_page_id );
301 if ( has_blocks( $content ) ) {
302 $blocks = parse_blocks( $content );
303 foreach ( $blocks as $block ) {
304 $output .= render_block( $block );
305 }
306 } else {
307 $content = apply_filters( 'the_content', $content );
308 $output = str_replace( ']]>', ']]&gt;', $content );
309 }
310 echo wp_kses_post( $output );
311 }
312 }
313