PluginProbe
Qi Blocks / trunk
Qi Blocks vtrunk
1.5.3 1.5.2 1.5.1 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1 1.1.1 1.1.2 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 All 45 releases
← All changes | inc/blocks/helper.php +487 -0 1.0.7 → trunk View file →
@@ -1,6 +1,493 @@
1 1 <?php
2 2
3 +if ( ! function_exists( 'qi_blocks_content_contains_block_reference' ) ) {
4 + /**
5 + * Check whether content references a Qi block by slug or namespace.
6 + *
7 + * @param string $content Post content, widget content, or rendered template HTML.
8 + * @param string $block_name Optional block slug without namespace.
9 + *
10 + * @return bool
11 + */
12 + function qi_blocks_content_contains_block_reference( $content, $block_name = '' ) {
13 + if ( empty( $content ) || ! is_string( $content ) ) {
14 + return false;
15 + }
16 +
17 + if ( '' === $block_name ) {
18 + if ( false !== strpos( $content, 'qi-blocks/' ) ) {
19 + return true;
20 + }
21 +
22 + return false !== strpos( $content, 'wp-block-qi-blocks-' );
23 + }
24 +
25 + if ( false !== strpos( $content, 'qi-blocks/' . $block_name ) ) {
26 + return true;
27 + }
28 +
29 + return false !== strpos( $content, 'wp-block-qi-blocks-' . $block_name );
30 + }
31 +}
32 +
33 +if ( ! function_exists( 'qi_blocks_parsed_blocks_contain_block' ) ) {
34 + /**
35 + * Recursively check parsed blocks for a Qi block, including reusable blocks.
36 + *
37 + * @param array $blocks Parsed blocks array.
38 + * @param string $block_name Optional block slug without namespace.
39 + *
40 + * @return bool
41 + */
42 + function qi_blocks_parsed_blocks_contain_block( $blocks, $block_name = '' ) {
43 + if ( empty( $blocks ) || ! is_array( $blocks ) ) {
44 + return false;
45 + }
46 +
47 + foreach ( $blocks as $block ) {
48 + if ( empty( $block['blockName'] ) ) {
49 + continue;
50 + }
51 +
52 + if ( '' === $block_name ) {
53 + if ( 0 === strpos( $block['blockName'], 'qi-blocks/' ) ) {
54 + return true;
55 + }
56 + } elseif ( 'qi-blocks/' . $block_name === $block['blockName'] ) {
57 + return true;
58 + }
59 +
60 + if ( 'core/block' === $block['blockName'] && ! empty( $block['attrs']['ref'] ) ) {
61 + $reusable_post = get_post( (int) $block['attrs']['ref'] );
62 +
63 + if ( $reusable_post && ! empty( $reusable_post->post_content ) ) {
64 + if ( qi_blocks_content_contains_block_reference( $reusable_post->post_content, $block_name ) ) {
65 + return true;
66 + }
67 +
68 + if ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_block( parse_blocks( $reusable_post->post_content ), $block_name ) ) {
69 + return true;
70 + }
71 + }
72 + }
73 +
74 + if ( 'core/template-part' === $block['blockName'] && ! empty( $block['attrs']['slug'] ) && function_exists( 'get_block_template' ) ) {
75 + $template_theme = ! empty( $block['attrs']['theme'] ) ? $block['attrs']['theme'] : get_stylesheet();
76 + $template_part = get_block_template( $template_theme . '//' . $block['attrs']['slug'], 'wp_template_part' );
77 +
78 + if ( $template_part && ! empty( $template_part->content ) ) {
79 + if ( qi_blocks_content_contains_block_reference( $template_part->content, $block_name ) ) {
80 + return true;
81 + }
82 +
83 + if ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_block( parse_blocks( $template_part->content ), $block_name ) ) {
84 + return true;
85 + }
86 + }
87 + }
88 +
89 + if ( ! empty( $block['innerBlocks'] ) && qi_blocks_parsed_blocks_contain_block( $block['innerBlocks'], $block_name ) ) {
90 + return true;
91 + }
92 + }
93 +
94 + return false;
95 + }
96 +}
97 +
98 +if ( ! function_exists( 'qi_blocks_page_contains_qi_blocks' ) ) {
99 + /**
100 + * Detect whether the current frontend request needs Qi Blocks assets.
101 + *
102 + * @return bool
103 + */
104 + function qi_blocks_page_contains_qi_blocks() {
105 + static $contains = null;
106 + static $resolving = false;
107 +
108 + if ( null !== $contains ) {
109 + return $contains;
110 + }
111 +
112 + if ( $resolving ) {
113 + return false;
114 + }
115 +
116 + $resolving = true;
117 + $contains = false;
118 +
119 + if ( is_admin() ) {
120 + $resolving = false;
121 +
122 + return $contains;
123 + }
124 +
125 + $page_id = get_queried_object_id();
126 +
127 + if ( $page_id ) {
128 + $post_content = get_post_field( 'post_content', $page_id );
129 +
130 + if ( qi_blocks_content_contains_block_reference( $post_content ) ) {
131 + $contains = true;
132 + $resolving = false;
133 +
134 + return $contains;
135 + }
136 +
137 + if ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_block( parse_blocks( $post_content ) ) ) {
138 + $contains = true;
139 + $resolving = false;
140 +
141 + return $contains;
142 + }
143 + }
144 +
145 + if ( ! $contains && function_exists( 'qi_blocks_get_block_template_content' ) && qi_blocks_should_resolve_block_template_html() ) {
146 + $template_content = qi_blocks_get_block_template_content();
147 +
148 + if ( qi_blocks_content_contains_block_reference( $template_content ) ) {
149 + $contains = true;
150 + } elseif ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_block( parse_blocks( $template_content ) ) ) {
151 + $contains = true;
152 + }
153 + }
154 +
155 + if ( ! $contains ) {
156 + $widgets_block = get_option( 'widget_block' );
157 +
158 + if ( ! empty( $widgets_block ) && is_array( $widgets_block ) ) {
159 + foreach ( $widgets_block as $widget_block ) {
160 + if ( isset( $widget_block['content'] ) && qi_blocks_content_contains_block_reference( $widget_block['content'] ) ) {
161 + $contains = true;
162 + break;
163 + }
164 + }
165 + }
166 + }
167 +
168 + $resolving = false;
169 +
170 + return $contains;
171 + }
172 +}
173 +
174 +if ( ! function_exists( 'qi_blocks_should_load_frontend_assets' ) ) {
175 + /**
176 + * Whether Qi Blocks frontend assets should be enqueued.
177 + *
178 + * @return bool
179 + */
180 + function qi_blocks_should_load_frontend_assets() {
181 + return (bool) apply_filters( 'qi_blocks_should_load_frontend_assets', qi_blocks_page_contains_qi_blocks() );
182 + }
183 +}
184 +
185 +if ( ! function_exists( 'qi_blocks_is_block_present_on_page' ) ) {
186 + /**
187 + * Check if a specific Qi block is present in post content, templates, or widgets.
188 + *
189 + * @param string $block_name Block slug without namespace.
190 + *
191 + * @return bool
192 + */
193 + function qi_blocks_is_block_present_on_page( $block_name ) {
194 + static $presence_cache = array();
195 +
196 + if ( isset( $presence_cache[ $block_name ] ) ) {
197 + return $presence_cache[ $block_name ];
198 + }
199 +
200 + $is_present = function_exists( 'has_block' ) && has_block( 'qi-blocks/' . $block_name );
201 +
202 + if ( ! $is_present ) {
203 + $page_id = get_queried_object_id();
204 +
205 + if ( $page_id ) {
206 + $post_content = get_post_field( 'post_content', $page_id );
207 +
208 + if ( qi_blocks_content_contains_block_reference( $post_content, $block_name ) ) {
209 + $is_present = true;
210 + } elseif ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_block( parse_blocks( $post_content ), $block_name ) ) {
211 + $is_present = true;
212 + }
213 + }
214 + }
215 +
216 + if ( ! $is_present && function_exists( 'qi_blocks_get_block_template_content' ) && qi_blocks_should_resolve_block_template_html() ) {
217 + $template_content = qi_blocks_get_block_template_content();
218 +
219 + if ( qi_blocks_content_contains_block_reference( $template_content, $block_name ) ) {
220 + $is_present = true;
221 + } elseif ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_block( parse_blocks( $template_content ), $block_name ) ) {
222 + $is_present = true;
223 + }
224 + }
225 +
226 + if ( ! $is_present ) {
227 + static $widgets_block = null;
228 +
229 + if ( null === $widgets_block ) {
230 + $widgets_block = get_option( 'widget_block' );
231 + }
232 +
233 + if ( ! empty( $widgets_block ) && is_array( $widgets_block ) ) {
234 + foreach ( $widgets_block as $widget_block ) {
235 + if ( isset( $widget_block['content'] ) && qi_blocks_content_contains_block_reference( $widget_block['content'], $block_name ) ) {
236 + $is_present = true;
237 + break;
238 + }
239 + }
240 + }
241 + }
242 +
243 + $presence_cache[ $block_name ] = $is_present;
244 +
245 + return $is_present;
246 + }
247 +}
248 +
249 +if ( ! function_exists( 'qi_blocks_get_slider_block_names' ) ) {
250 + /**
251 + * Block slugs that require the Swiper library on the frontend.
252 + *
253 + * @return array
254 + */
255 + function qi_blocks_get_slider_block_names() {
256 + return (array) apply_filters(
257 + 'qi_blocks_filter_slider_block_names',
258 + array(
259 + 'image-slider',
260 + 'blog-slider',
261 + 'product-slider',
262 + 'clients-slider',
263 + 'testimonials-slider',
264 + 'device-slider',
265 + 'device-carousel',
266 + 'preview-slider',
267 + 'slider-switch',
268 + )
269 + );
270 + }
271 +}
272 +
273 +if ( ! function_exists( 'qi_blocks_parsed_blocks_contain_slider_block' ) ) {
274 + /**
275 + * Recursively check parsed blocks for any Qi slider block.
276 + *
277 + * @param array $blocks Parsed blocks array.
278 + *
279 + * @return bool
280 + */
281 + function qi_blocks_parsed_blocks_contain_slider_block( $blocks ) {
282 + foreach ( qi_blocks_get_slider_block_names() as $slider_block_name ) {
283 + if ( qi_blocks_parsed_blocks_contain_block( $blocks, $slider_block_name ) ) {
284 + return true;
285 + }
286 + }
287 +
288 + return false;
289 + }
290 +}
291 +
292 +if ( ! function_exists( 'qi_blocks_content_contains_swiper_markup' ) ) {
293 + /**
294 + * Whether content includes rendered Qi slider markup.
295 + *
296 + * @param string $content Optional content string.
297 + *
298 + * @return bool
299 + */
300 + function qi_blocks_content_contains_swiper_markup( $content = '' ) {
301 + if ( is_string( $content ) && '' !== $content ) {
302 + return false !== strpos( $content, 'qodef-block-swiper' );
303 + }
304 +
305 + $page_id = get_queried_object_id();
306 +
307 + if ( $page_id ) {
308 + $post_content = get_post_field( 'post_content', $page_id );
309 +
310 + if ( false !== strpos( $post_content, 'qodef-block-swiper' ) ) {
311 + return true;
312 + }
313 + }
314 +
315 + if ( function_exists( 'qi_blocks_get_block_template_content' ) && qi_blocks_should_resolve_block_template_html() ) {
316 + $template_content = qi_blocks_get_block_template_content();
317 +
318 + foreach ( qi_blocks_get_slider_block_names() as $slider_block_name ) {
319 + if ( qi_blocks_content_contains_block_reference( $template_content, $slider_block_name ) ) {
320 + return true;
321 + }
322 + }
323 +
324 + if ( function_exists( 'parse_blocks' ) && qi_blocks_parsed_blocks_contain_slider_block( parse_blocks( $template_content ) ) ) {
325 + return true;
326 + }
327 + }
328 +
329 + $widgets_block = get_option( 'widget_block' );
330 +
331 + if ( ! empty( $widgets_block ) && is_array( $widgets_block ) ) {
332 + foreach ( $widgets_block as $widget_block ) {
333 + if ( isset( $widget_block['content'] ) && false !== strpos( $widget_block['content'], 'qodef-block-swiper' ) ) {
334 + return true;
335 + }
336 + }
337 + }
338 +
339 + return false;
340 + }
341 +}
342 +
343 +if ( ! function_exists( 'qi_blocks_page_needs_swiper' ) ) {
344 + /**
345 + * Whether the current request needs the Swiper library.
346 + *
347 + * @return bool
348 + */
349 + function qi_blocks_page_needs_swiper() {
350 + static $needs_swiper = null;
351 +
352 + if ( null !== $needs_swiper ) {
353 + return $needs_swiper;
354 + }
355 +
356 + $needs_swiper = false;
357 +
358 + foreach ( qi_blocks_get_slider_block_names() as $slider_block_name ) {
359 + if ( qi_blocks_is_block_present_on_page( $slider_block_name ) ) {
360 + $needs_swiper = true;
361 +
362 + return $needs_swiper;
363 + }
364 + }
365 +
366 + if ( qi_blocks_content_contains_swiper_markup() ) {
367 + $needs_swiper = true;
368 + }
369 +
370 + return $needs_swiper;
371 + }
372 +}
373 +
374 +if ( ! function_exists( 'qi_blocks_should_enqueue_third_party_script' ) ) {
375 + /**
376 + * Whether a shared 3rd party script should be enqueued.
377 + *
378 + * @param string $script_key Script handle.
379 + * @param array $script_value Script config.
380 + * @param bool $editor_mode Whether the editor is loading assets.
381 + *
382 + * @return bool
383 + */
384 + function qi_blocks_should_enqueue_third_party_script( $script_key, $script_value, $editor_mode = false ) {
385 + if ( $editor_mode ) {
386 + return true;
387 + }
388 +
389 + if ( 'swiper' === $script_key ) {
390 + return qi_blocks_page_needs_swiper();
391 + }
392 +
393 + $block_names = array();
394 +
395 + if ( ! empty( $script_value['block_names'] ) && is_array( $script_value['block_names'] ) ) {
396 + $block_names = $script_value['block_names'];
397 + } elseif ( ! empty( $script_value['block_name'] ) ) {
398 + $block_names = array( $script_value['block_name'] );
399 + }
400 +
401 + if ( empty( $block_names ) ) {
402 + return true;
403 + }
404 +
405 + foreach ( $block_names as $block_name ) {
406 + if ( qi_blocks_is_block_present_on_page( $block_name ) ) {
407 + return true;
408 + }
409 + }
410 +
411 + return false;
412 + }
413 +}
414 +
415 +if ( ! function_exists( 'qi_blocks_should_resolve_block_template_html' ) ) {
416 + /**
417 + * Whether block template content should be resolved for frontend asset loading.
418 + *
419 + * @return bool
420 + */
421 + function qi_blocks_should_resolve_block_template_html() {
422 + $should_resolve = function_exists( 'wp_is_block_theme' ) && wp_is_block_theme();
423 +
424 + return (bool) apply_filters( 'qi_blocks_should_resolve_block_template_html', $should_resolve );
425 + }
426 +}
427 +
428 +if ( ! function_exists( 'qi_blocks_get_block_template_content' ) ) {
429 + /**
430 + * Return raw block template content for the current request.
431 + *
432 + * Does not render blocks — safe to call during wp_enqueue_scripts.
433 + *
434 + * @return string
435 + */
436 + function qi_blocks_get_block_template_content() {
437 + static $request_cache = null;
438 +
439 + if ( null !== $request_cache ) {
440 + return $request_cache;
441 + }
442 +
443 + if ( ! qi_blocks_should_resolve_block_template_html() ) {
444 + $request_cache = '';
445 +
446 + return $request_cache;
447 + }
448 +
449 + global $_wp_current_template_content;
450 +
451 + if ( empty( $_wp_current_template_content ) || ! is_string( $_wp_current_template_content ) ) {
452 + $request_cache = '';
453 +
454 + return $request_cache;
455 + }
456 +
457 + $request_cache = $_wp_current_template_content;
458 +
459 + return $request_cache;
460 + }
461 +}
462 +
463 +if ( ! function_exists( 'qi_blocks_get_the_block_template_html' ) ) {
464 + /**
465 + * Backward-compatible alias for raw template content used in asset detection.
466 + *
467 + * @deprecated Never calls get_the_block_template_html() — rendering blocks during asset detection caused duplicate script loads in the Site Editor.
468 + *
469 + * @return string Raw block template content.
470 + */
471 + function qi_blocks_get_the_block_template_html() {
472 + return qi_blocks_get_block_template_content();
473 + }
474 +}
475 +
476 +if ( ! function_exists( 'qi_blocks_cleanup_legacy_block_template_transient' ) ) {
477 + /**
478 + * Remove legacy transient key that contained a trailing space.
479 + *
480 + * @return void
481 + */
482 + function qi_blocks_cleanup_legacy_block_template_transient() {
483 + delete_transient( '_qi_blocks_get_the_block_template_html' );
484 + delete_transient( '_qi_blocks_get_the_block_template_html ' );
485 + }
486 +
487 + add_action( 'init', 'qi_blocks_cleanup_legacy_block_template_transient', 1 );
488 +}
489 +
3 490 if ( ! function_exists( 'qi_blocks_get_premium_blocks_list' ) ) {
4 491 /**
5 492 * Function that return premium blocks list
6 493 *