PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.5.3
GenerateBlocks v1.5.3
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / includes / functions.php
generateblocks / includes Last commit date
class-do-css.php 4 years ago class-dynamic-content.php 4 years ago class-enqueue-css.php 4 years ago class-legacy-attributes.php 4 years ago class-plugin-update.php 5 years ago class-query-loop.php 3 years ago class-render-blocks.php 3 years ago class-rest.php 4 years ago class-settings.php 4 years ago dashboard.php 4 years ago defaults.php 4 years ago functions.php 4 years ago general.php 4 years ago generate-css.php 4 years ago
functions.php
896 lines
1 <?php
2 /**
3 * Functions used throughout the plugin.
4 *
5 * @package GenerateBlocks
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 /**
13 * Retrive attributes from our blocks.
14 *
15 * @since 0.1
16 * @param array $content The content of our page.
17 * @param array $data Data used to loop through the function as needed.
18 * @param int $depth Keep track of how deep we are in nested blocks.
19 *
20 * @return array
21 */
22 function generateblocks_get_block_data( $content, $data = array(), $depth = 0 ) {
23 if ( ! is_array( $content ) || empty( $content ) ) {
24 return;
25 }
26
27 foreach ( $content as $index => $block ) {
28 if ( ! is_object( $block ) && is_array( $block ) && isset( $block['blockName'] ) ) {
29 if ( 'generateblocks/grid' === $block['blockName'] ) {
30 $data['grid'][] = $block['attrs'];
31 $depth++;
32 $data[ 'tempGridId-' . $depth ] = $block['attrs']['uniqueId'];
33 }
34
35 if ( 'generateblocks/container' === $block['blockName'] ) {
36 if ( isset( $block['attrs']['isGrid'] ) && $block['attrs']['isGrid'] && isset( $data[ 'tempGridId-' . $depth ] ) ) {
37 $block['attrs']['gridId'] = $data[ 'tempGridId-' . $depth ];
38 }
39
40 $data['container'][] = $block['attrs'];
41 }
42
43 if ( 'generateblocks/headline' === $block['blockName'] ) {
44 if ( isset( $block['innerHTML'] ) ) {
45 if ( strpos( trim( $block['innerHTML'] ), '<div class="gb-headline-wrapper' ) === 0 ) {
46 $block['attrs']['hasWrapper'] = true;
47 }
48 }
49
50 $data['headline'][] = $block['attrs'];
51 }
52
53 if ( 'generateblocks/button-container' === $block['blockName'] ) {
54 $data['button-container'][] = $block['attrs'];
55 }
56
57 if ( 'generateblocks/button' === $block['blockName'] ) {
58 if ( ! isset( $block['attrs']['hasUrl'] ) && isset( $block['innerHTML'] ) ) {
59 if ( strpos( trim( $block['innerHTML'] ), '<a' ) === 0 ) {
60 $block['attrs']['hasUrl'] = true;
61 }
62 }
63
64 $data['button'][] = $block['attrs'];
65 }
66
67 if ( 'generateblocks/image' === $block['blockName'] ) {
68 $data['image'][] = $block['attrs'];
69 }
70
71 if ( 'core/block' === $block['blockName'] ) {
72 if ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) {
73 $atts = $block['attrs'];
74
75 if ( isset( $atts['ref'] ) && ( empty( $data['reusableBlockIds'] ) || ! in_array( $atts['ref'], (array) $data['reusableBlockIds'] ) ) ) {
76 $reusable_block = get_post( $atts['ref'] );
77
78 if ( $reusable_block && 'wp_block' === $reusable_block->post_type && 'publish' === $reusable_block->post_status ) {
79 $reuse_data_block = parse_blocks( $reusable_block->post_content );
80
81 if ( ! empty( $reuse_data_block ) ) {
82 $data['reusableBlockIds'][] = $atts['ref'];
83 $data = generateblocks_get_block_data( $reuse_data_block, $data );
84 }
85 }
86 }
87 }
88 }
89
90 if ( isset( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
91 $data = generateblocks_get_block_data( $block['innerBlocks'], $data, $depth );
92 }
93 }
94 }
95
96 return $data;
97 }
98
99 /**
100 * Parse our content for blocks.
101 *
102 * @param string $content Optional content to parse.
103 * @since 1.1
104 */
105 function generateblocks_get_parsed_content( $content = '' ) {
106 if ( ! function_exists( 'has_blocks' ) ) {
107 return;
108 }
109
110 if ( ! $content && has_blocks( get_the_ID() ) ) {
111 global $post;
112
113 if ( ! is_object( $post ) ) {
114 return;
115 }
116
117 $content = $post->post_content;
118 }
119
120 $content = apply_filters( 'generateblocks_do_content', $content );
121
122 if ( ! function_exists( 'parse_blocks' ) ) {
123 return;
124 }
125
126 $content = parse_blocks( $content );
127
128 return $content;
129 }
130
131 /**
132 * Shorthand CSS values (padding, margin, border etc..).
133 *
134 * @since 0.1
135 *
136 * @param int $top The first value.
137 * @param int $right The second value.
138 * @param int $bottom The third value.
139 * @param int $left The fourth value.
140 * @param string $unit The unit we're adding.
141 *
142 * @return string The shorthand value.
143 */
144 function generateblocks_get_shorthand_css( $top, $right, $bottom, $left, $unit ) {
145 if ( '' === $top && '' === $right && '' === $bottom && '' === $left ) {
146 return;
147 }
148
149 $top = ( floatval( $top ) <> 0 ) ? floatval( $top ) . $unit . ' ' : '0 '; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
150 $right = ( floatval( $right ) <> 0 ) ? floatval( $right ) . $unit . ' ' : '0 '; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
151 $bottom = ( floatval( $bottom ) <> 0 ) ? floatval( $bottom ) . $unit . ' ' : '0 '; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
152 $left = ( floatval( $left ) <> 0 ) ? floatval( $left ) . $unit . ' ' : '0 '; // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
153
154 if ( $right === $left ) {
155 $left = '';
156
157 if ( $top === $bottom ) {
158 $bottom = '';
159
160 if ( $top === $right ) {
161 $right = '';
162 }
163 }
164 }
165
166 return trim( $top . $right . $bottom . $left );
167 }
168
169 /**
170 * Get our media query.
171 *
172 * @since 0.1
173 * @param string $type The media query we're getting.
174 *
175 * @return string
176 */
177 function generateblocks_get_media_query( $type ) {
178 $queries = apply_filters(
179 'generateblocks_media_query',
180 array(
181 'desktop' => '(min-width: 1025px)',
182 'tablet' => '(max-width: 1024px)',
183 'tablet_only' => '(max-width: 1024px) and (min-width: 768px)',
184 'mobile' => '(max-width: 767px)',
185 )
186 );
187
188 return $queries[ $type ];
189 }
190
191 /**
192 * Build our list of Google fonts on this page.
193 *
194 * @since 0.1
195 * @param string $content Optional content to parse.
196 * @return array
197 */
198 function generateblocks_get_google_fonts( $content = '' ) {
199 $content = generateblocks_get_parsed_content( $content );
200
201 if ( ! $content ) {
202 return;
203 }
204
205 $data = generateblocks_get_block_data( $content );
206
207 $defaults = generateblocks_get_block_defaults();
208 $font_data = array();
209
210 if ( ! empty( $data ) ) {
211 foreach ( $data as $name => $blockData ) {
212 if ( 'button' === $name ) {
213 foreach ( $blockData as $atts ) {
214 $button_settings = wp_parse_args(
215 $atts,
216 $defaults['button']
217 );
218
219 if ( $button_settings['googleFont'] ) {
220 $id = $atts['uniqueId'];
221
222 $variants = $button_settings['googleFontVariants'];
223
224 if ( $variants ) {
225 $variants = str_replace( ' ', '', $variants );
226 $variants = explode( ',', $variants );
227 }
228
229 $font_data[ $id ] = array(
230 'name' => $button_settings['fontFamily'],
231 'variants' => $variants,
232 );
233 }
234 }
235 }
236
237 if ( 'headline' === $name ) {
238 foreach ( $blockData as $atts ) {
239 $headline_settings = wp_parse_args(
240 $atts,
241 $defaults['headline']
242 );
243
244 if ( $headline_settings['googleFont'] ) {
245 $id = $atts['uniqueId'];
246 $variants = $headline_settings['googleFontVariants'];
247
248 if ( $variants ) {
249 $variants = str_replace( ' ', '', $variants );
250 $variants = explode( ',', $variants );
251 }
252
253 $font_data[ $id ] = array(
254 'name' => $headline_settings['fontFamily'],
255 'variants' => $variants,
256 );
257 }
258 }
259 }
260
261 if ( 'container' === $name ) {
262 foreach ( $blockData as $atts ) {
263 $container_settings = wp_parse_args(
264 $atts,
265 $defaults['container']
266 );
267
268 if ( $container_settings['googleFont'] ) {
269 $id = $atts['uniqueId'];
270 $variants = $container_settings['googleFontVariants'];
271
272 if ( $variants ) {
273 $variants = str_replace( ' ', '', $variants );
274 $variants = explode( ',', $variants );
275 }
276
277 $font_data[ $id ] = array(
278 'name' => $container_settings['fontFamily'],
279 'variants' => $variants,
280 );
281 }
282 }
283 }
284 }
285 }
286
287 $fonts = array();
288
289 foreach ( (array) $font_data as $font ) {
290 $id = str_replace( ' ', '', strtolower( $font['name'] ) );
291
292 $fonts[ $id ]['name'] = $font['name'];
293
294 if ( ! empty( $font['variants'] ) ) {
295 foreach ( $font['variants'] as $variant ) {
296 if ( isset( $fonts[ $id ]['variants'] ) ) {
297 if ( in_array( $variant, (array) $fonts[ $id ]['variants'] ) ) {
298 continue;
299 }
300 }
301
302 $fonts[ $id ]['variants'][] = $variant;
303 }
304 }
305 }
306
307 return apply_filters( 'generateblocks_google_fonts', $fonts );
308 }
309
310 /**
311 * Build the Google Font request URI.
312 *
313 * @since 0.1
314 *
315 * @return string The request URI to Google Fonts.
316 */
317 function generateblocks_get_google_fonts_uri() {
318 $google_fonts = generateblocks_get_google_fonts();
319
320 if ( ! $google_fonts ) {
321 return;
322 }
323
324 $data = array();
325
326 foreach ( $google_fonts as $font ) {
327 $variants = array();
328
329 if ( ! empty( $font['variants'] ) ) {
330 foreach ( $font['variants'] as $variant ) {
331 $variants[] = $variant;
332 }
333 }
334
335 $variants = apply_filters( 'generateblocks_google_font_variants', $variants, $font['name'] );
336
337 $name = str_replace( ' ', '+', $font['name'] );
338
339 if ( $variants ) {
340 $data[] = $name . ':' . implode( ',', $variants );
341 } else {
342 $data[] = $name;
343 }
344 }
345
346 $font_args = apply_filters(
347 'generateblocks_google_font_args',
348 array(
349 'family' => implode( '|', $data ),
350 'subset' => null,
351 'display' => 'swap',
352 )
353 );
354
355 return add_query_arg( $font_args, 'https://fonts.googleapis.com/css' );
356 }
357
358 /**
359 * Convert hex to RGBA
360 *
361 * @since 0.1
362 * @param string $hex The hex value.
363 * @param int $alpha The opacity value.
364 *
365 * @return string The RGBA value.
366 */
367 function generateblocks_hex2rgba( $hex, $alpha ) {
368 if ( ! $hex ) {
369 return;
370 }
371
372 if ( 1 === $alpha || ! is_numeric( $alpha ) ) {
373 return $hex;
374 }
375
376 // Make sure we're dealing with a hex value.
377 if ( isset( $hex[0] ) && '#' !== $hex[0] ) {
378 return $hex;
379 }
380
381 $hex = str_replace( '#', '', $hex );
382
383 if ( strlen( $hex ) == 3 ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
384 $r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
385 $g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
386 $b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
387 } else {
388 $r = hexdec( substr( $hex, 0, 2 ) );
389 $g = hexdec( substr( $hex, 2, 2 ) );
390 $b = hexdec( substr( $hex, 4, 2 ) );
391 }
392
393 $rgba = 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $alpha . ')';
394
395 return $rgba;
396 }
397
398 /**
399 * Return old flexblocks values for old browsers.
400 *
401 * @since 0.1
402 * @param string $value The value to convert.
403 *
404 * @return string The old browser value.
405 */
406 function generateblocks_get_vendor_prefix( $value ) {
407 if ( 'flex-start' === $value || 'left' === $value ) {
408 return 'start';
409 }
410
411 if ( 'flex-end' === $value || 'right' === $value ) {
412 return 'end';
413 }
414
415 return $value;
416 }
417
418 /**
419 * Return flexbox alignment values from left/right.
420 *
421 * @since 0.1
422 * @param string $value The value to convert.
423 *
424 * @return string The flexbox alignment value.
425 */
426 function generateblocks_get_flexbox_alignment( $value ) {
427 if ( 'left' === $value || 'top' === $value ) {
428 return 'flex-start';
429 }
430
431 if ( 'right' === $value || 'bottom' === $value ) {
432 return 'flex-end';
433 }
434
435 return $value;
436 }
437
438 /**
439 * Return float alignment values.
440 *
441 * @since 1.5.0
442 * @param string $value The value to convert.
443 *
444 * @return string The float alignment value.
445 */
446 function generateblocks_get_float_alignment( $value ) {
447 $floats = [
448 'floatLeft' => 'left',
449 'floatRight' => 'right',
450 'floatNone' => 'none',
451 ];
452
453 return isset( $floats[ $value ] )
454 ? $floats[ $value ]
455 : $value;
456 }
457
458 /**
459 * Get an option from the database.
460 *
461 * @param string $option The option to get.
462 * @since 0.1
463 */
464 function generateblocks_get_option( $option ) {
465 $defaults = generateblocks_get_option_defaults();
466
467 if ( ! isset( $defaults[ $option ] ) ) {
468 return;
469 }
470
471 $options = wp_parse_args(
472 get_option( 'generateblocks', array() ),
473 $defaults
474 );
475
476 return $options[ $option ];
477 }
478
479 /**
480 * Checks whether a value exists, even if it's a 0.
481 *
482 * @param int|string $value The value to check.
483 * @since 1.0
484 */
485 function generateblocks_has_number_value( $value ) {
486 if ( $value || 0 === $value || '0' === $value ) {
487 return true;
488 }
489
490 return false;
491 }
492
493 /**
494 * Check if we have a Container background image to display.
495 *
496 * @since 1.5.0
497 * @param array $settings The block settings.
498 */
499 function generateblocks_has_background_image( $settings ) {
500 return $settings['bgImage'] ||
501 (
502 $settings['useDynamicData'] &&
503 '' !== $settings['dynamicContentType']
504 );
505 }
506
507 /**
508 * Get our background image URL.
509 *
510 * @since 1.5.0
511 * @param array $settings Block settings.
512 */
513 function generateblocks_get_background_image_url( $settings ) {
514 $url = '';
515
516 if ( isset( $settings['bgImage']['id'] ) ) {
517 $image_src = wp_get_attachment_image_src( $settings['bgImage']['id'], $settings['bgImageSize'] );
518
519 if ( is_array( $image_src ) ) {
520 $url = $image_src[0];
521 } else {
522 $url = $settings['bgImage']['image']['url'];
523 }
524 } elseif ( isset( $settings['bgImage']['image']['url'] ) ) {
525 $url = $settings['bgImage']['image']['url'];
526 }
527
528 return apply_filters( 'generateblocks_background_image_url', $url, $settings );
529 }
530
531 /**
532 * Get the background-image value for our Container block.
533 *
534 * @param string $type Gradient or background image.
535 * @param array $settings Our background image settings.
536 */
537 function generateblocks_get_background_image_css( $type, $settings ) {
538 $gradient = '';
539
540 if ( $settings['gradient'] ) {
541 $gradientColorStopOneValue = '';
542 $gradientColorStopTwoValue = '';
543 $gradientColorOneValue = generateblocks_hex2rgba( $settings['gradientColorOne'], $settings['gradientColorOneOpacity'] );
544 $gradientColorTwoValue = generateblocks_hex2rgba( $settings['gradientColorTwo'], $settings['gradientColorTwoOpacity'] );
545
546 if ( $settings['gradientColorOne'] && '' !== $settings['gradientColorStopOne'] ) {
547 $gradientColorStopOneValue = ' ' . $settings['gradientColorStopOne'] . '%';
548 }
549
550 if ( $settings['gradientColorTwo'] && '' !== $settings['gradientColorStopTwo'] ) {
551 $gradientColorStopTwoValue = ' ' . $settings['gradientColorStopTwo'] . '%';
552 }
553
554 $gradient = 'linear-gradient(' . $settings['gradientDirection'] . 'deg, ' . $gradientColorOneValue . $gradientColorStopOneValue . ', ' . $gradientColorTwoValue . $gradientColorStopTwoValue . ')';
555 }
556
557 if ( 'gradient' === $type ) {
558 return $gradient;
559 }
560
561 $backgroundImage = '';
562
563 if ( generateblocks_has_background_image( $settings ) ) {
564 $url = generateblocks_get_background_image_url( $settings );
565
566 // Old background image overlays mixed with our gradients.
567 if (
568 'element' === $settings['bgOptions']['selector'] &&
569 ( $settings['backgroundColor'] || $settings['gradient'] ) &&
570 isset( $settings['bgOptions']['overlay'] ) &&
571 $settings['bgOptions']['overlay']
572 ) {
573 if ( $settings['gradient'] ) {
574 $backgroundImage = $gradient . ', url(' . esc_url( $url ) . ')';
575 } elseif ( $settings['backgroundColor'] ) {
576 $settings['backgroundColor'] = generateblocks_hex2rgba( $settings['backgroundColor'], $settings['backgroundColorOpacity'] );
577 $backgroundImage = 'linear-gradient(0deg, ' . $settings['backgroundColor'] . ', ' . $settings['backgroundColor'] . '), url(' . esc_url( $url ) . ')';
578 }
579 } else {
580 $backgroundImage = 'url(' . esc_url( $url ) . ')';
581
582 if ( $settings['bgImageInline'] && 'element' !== $settings['bgOptions']['selector'] ) {
583 $backgroundImage = 'var(--background-image)';
584 }
585 }
586 }
587
588 return $backgroundImage;
589 }
590
591 /**
592 * Build list of attributes into a string and apply contextual filter on string.
593 *
594 * The contextual filter is of the form `generateblocks_attr_{context}_output`.
595 *
596 * @since 1.2.0
597 *
598 * @param string $context The context, to build filter name.
599 * @param array $attributes Optional. Extra attributes to merge with defaults.
600 * @param array $settings Optional. Custom data to pass to filter.
601 * @param WP_Block $block Block instance.
602 * @return string String of HTML attributes and values.
603 */
604 function generateblocks_attr( $context, $attributes = array(), $settings = array(), $block = null ) {
605 $attributes = generateblocks_parse_attr( $context, $attributes, $settings );
606
607 $output = '';
608
609 // Cycle through attributes, build tag attribute string.
610 foreach ( $attributes as $key => $value ) {
611
612 if ( ! $value ) {
613 continue;
614 }
615
616 if ( true === $value ) {
617 $output .= esc_html( $key ) . ' ';
618 } else {
619 $output .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
620 }
621 }
622
623 $output = apply_filters( "generateblocks_attr_{$context}_output", $output, $attributes, $settings, $context, $block );
624
625 return trim( $output );
626 }
627
628 /**
629 * Merge array of attributes with defaults, and apply contextual filter on array.
630 *
631 * The contextual filter is of the form `generateblocks_attr_{context}`.
632 *
633 * @since 1.2.0
634 *
635 * @param string $context The context, to build filter name.
636 * @param array $attributes Optional. Extra attributes to merge with defaults.
637 * @param array $settings Optional. Custom data to pass to filter.
638 * @param WP_Block $block Block instance.
639 * @return array Merged and filtered attributes.
640 */
641 function generateblocks_parse_attr( $context, $attributes = array(), $settings = array(), $block = null ) {
642 $defaults = array(
643 'class' => sanitize_html_class( $context ),
644 );
645
646 $attributes = wp_parse_args( $attributes, $defaults );
647
648 // Contextual filter.
649 return apply_filters( "generateblocks_attr_{$context}", $attributes, $settings, $context, $block );
650 }
651
652 /**
653 * Generate our SVG shape dividers.
654 *
655 * @since 1.2.0
656 */
657 function generateblocks_get_svg_shapes() {
658 return apply_filters(
659 'generateblocks_svg_shapes',
660 array(
661 'gb-waves' => array(
662 'group' => esc_attr__( 'Waves', 'generateblocks' ),
663 'svgs' => array(
664 'gb-waves-1' => array(
665 /* translators: Shape number */
666 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '1' ),
667 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 194.3" preserveAspectRatio="none"><path d="M1200 133.3l-50 8.9c-50 8.6-150 26.9-250 31.1-100 4.2-200-4.2-300-26.7S400 89.2 300 62.2C200 35.8 100 17.5 50 8.9L0 0v194.3h1200v-61z"/></svg>',
668 ),
669 'gb-waves-2' => array(
670 /* translators: Shape number */
671 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '2' ),
672 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 137.6" preserveAspectRatio="none"><path d="M0 137.6h1200V21.9l-66.7 26.7c-66.7 26.7-200 80-333.3 66.7S533.3 21.9 400 4.2C266.7-13.9 133.3 31.1 66.7 53L0 75.3v62.3z"/></svg>',
673 ),
674 'gb-waves-3' => array(
675 /* translators: Shape number */
676 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '3' ),
677 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 96.2" preserveAspectRatio="none"><path d="M0 96.2h1200V72.9l-50-8.9c-50-8.6-150-26.9-250-22.2C800 46.2 700 72.9 600 64 500 55.4 400 10.4 300 1.8 200-7.1 100 19.5 50 32.9L0 46.2v50z"/></svg>',
678 ),
679 'gb-waves-4' => array(
680 /* translators: Shape number */
681 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '4' ),
682 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 130.3" preserveAspectRatio="none"><path d="M0 107.9l40-22.2c40-21.9 120-66.9 200-62.2 80 4.4 160 57.8 240 53.3C560 72 640 10.4 720 1.2S880 37 960 59c80 22.3 160 22.3 200 22.3h40v49H0v-22.4z"/></svg>',
683 ),
684 'gb-waves-5' => array(
685 /* translators: Shape number */
686 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '5' ),
687 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 218" preserveAspectRatio="none"><path d="M0 218h1200v-31.3l-40 4.4c-40 4.8-120 13.1-200 0-80-13.6-160-48.6-240-66.7-80-17.8-160-17.8-240-8.8-80 8.6-160 26.9-240 8.8-80-17.7-160-71.1-200-97.7L0 0v218z"/></svg>',
688 ),
689 'gb-waves-6' => array(
690 /* translators: Shape number */
691 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '6' ),
692 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 234" preserveAspectRatio="none"><path d="M0 0l40 40c40 40 120 120 200 115.6 80-4.8 160-93.1 240-111.2C560 26.7 640 80 720 88.9c80 8.6 160-26.4 240-13.3 80 13.6 160 75.2 200 106.7l40 31.1V234H0V0z"/></svg>',
693 ),
694 'gb-waves-7' => array(
695 /* translators: Shape number */
696 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '7' ),
697 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 217.3" preserveAspectRatio="none"><path d="M1200 195.6l-25-22.2c-25-21.9-75-66.9-125-75.5-50-8.9-100 17.8-150 26.7-50 8.6-100 .2-150-13.3-50-13.1-100-31.4-150-26.7-50 4.4-100 31.1-150 26.7-50-4.8-100-39.8-150-66.7C250 18.1 200-.2 150 0 100-.2 50 18.1 25 26.7L0 35.6v181.7h1200v-21.7z"/></svg>',
698 ),
699 'gb-waves-8' => array(
700 /* translators: Shape number */
701 'label' => sprintf( __( 'Wave %s', 'generateblocks' ), '8' ),
702 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 230.8" preserveAspectRatio="none"><path d="M1200 179.5l-22.2-26.7c-22.2-26.7-66.9-80-111.1-75.6-44.4 4.8-89.2 66.4-133.3 102.2-44.4 35.8-89.2 44.2-133.3 8.9-44.4-35.6-89.2-115.6-133.3-155.6-44.4-40-89.2-40-133.3-17.8C488.9 37 444.2 82 400 81.7c-44.4.2-89.2-44.8-133.3-57.8-44.4-13.6-89.2 4.8-133.3 26.7-44.5 22.2-89.2 48.9-110.9 62.2L0 126.1v104.7H1199.7l.3-51.3z"/></svg>',
703 ),
704 ),
705 ),
706 'gb-angles' => array(
707 'group' => esc_attr__( 'Angles', 'generateblocks' ),
708 'svgs' => array(
709 'gb-angle-1' => array(
710 /* translators: Shape number */
711 'label' => sprintf( __( 'Angle %s', 'generateblocks' ), '1' ),
712 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 360" preserveAspectRatio="none"><path d="M1200 360H0V0l1200 348z"/></svg>',
713 ),
714 ),
715 ),
716 'gb-curves' => array(
717 'group' => esc_attr__( 'Curves', 'generateblocks' ),
718 'svgs' => array(
719 'gb-curve-1' => array(
720 /* translators: Shape number */
721 'label' => sprintf( __( 'Curve %s', 'generateblocks' ), '1' ),
722 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 350" preserveAspectRatio="none"><path d="M1200 336.7V350H0V0s22.4 276.4 1200 336.7z"/></svg>',
723 ),
724 'gb-curve-2' => array(
725 /* translators: Shape number */
726 'label' => sprintf( __( 'Curve %s', 'generateblocks' ), '2' ),
727 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 350" preserveAspectRatio="none"><path d="M1200 350V0C22.4 60.3 0 336.7 0 336.7V350h1200z"/></svg>',
728 ),
729 'gb-curve-3' => array(
730 /* translators: Shape number */
731 'label' => sprintf( __( 'Curve %s', 'generateblocks' ), '3' ),
732 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 211.2" preserveAspectRatio="none"><path d="M600 188.4C321.1 188.4 84.3 109.5 0 0v211.2h1200V0c-84.3 109.5-321.1 188.4-600 188.4z"/></svg>',
733 ),
734 'gb-curve-4' => array(
735 /* translators: Shape number */
736 'label' => sprintf( __( 'Curve %s', 'generateblocks' ), '4' ),
737 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 211.2" preserveAspectRatio="none"><path d="M1200 188.4v22.8H0v-22.8C84.3 78.9 321.1 0 600 0s515.7 78.9 600 188.4z"/></svg>',
738 ),
739 ),
740 ),
741 'gb-triangles' => array(
742 'group' => esc_attr__( 'Triangles', 'generateblocks' ),
743 'svgs' => array(
744 'gb-triangle-1' => array(
745 /* translators: Shape number */
746 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '1' ),
747 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 100" preserveAspectRatio="none"><path d="M1200 100H0V0l400 77.2L1200 0z"/></svg>',
748 ),
749 'gb-triangle-2' => array(
750 /* translators: Shape number */
751 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '2' ),
752 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 100" preserveAspectRatio="none"><path d="M1200 77.2L400 0 0 77.2V100h1200z"/></svg>',
753 ),
754 'gb-triangle-3' => array(
755 /* translators: Shape number */
756 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '3' ),
757 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 70" preserveAspectRatio="none"><path d="M1200 0v70H0V0h530l70 50 70-50z"/></svg>',
758 ),
759 'gb-triangle-4' => array(
760 /* translators: Shape number */
761 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '4' ),
762 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 70" preserveAspectRatio="none"><path d="M670 50L600 0l-70 50H0v20h1200V50z"/></svg>',
763 ),
764 'gb-triangle-5' => array(
765 /* translators: Shape number */
766 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '5' ),
767 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 50" preserveAspectRatio="none"><path d="M1200 0v50H0V0h560l40 30 40-30z"/></svg>',
768 ),
769 'gb-triangle-6' => array(
770 /* translators: Shape number */
771 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '6' ),
772 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 50" preserveAspectRatio="none"><path d="M640 30L600 0l-40 30H0v20h1200V30z"/></svg>',
773 ),
774 'gb-triangle-7' => array(
775 /* translators: Shape number */
776 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '7' ),
777 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 230" preserveAspectRatio="none"><path d="M1200 230H0V0l600 207.2L1200 0z"/></svg>',
778 ),
779 'gb-triangle-8' => array(
780 /* translators: Shape number */
781 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '8' ),
782 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 230" preserveAspectRatio="none"><path d="M1200 207.2L600 0 0 207.2V230h1200z"/></svg>',
783 ),
784 'gb-triangle-9' => array(
785 /* translators: Shape number */
786 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '9' ),
787 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 131" preserveAspectRatio="none"><path d="M1200 131H0V40l154.8 50L410 35l277 69L899 0l301 110z"/></svg>',
788 ),
789 'gb-triangle-10' => array(
790 /* translators: Shape number */
791 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '10' ),
792 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 131" preserveAspectRatio="none"><path d="M1200 0L899 110 687 6 410 75 154.8 20 0 70v61h1200z"/></svg>',
793 ),
794 'gb-triangle-11' => array(
795 /* translators: Shape number */
796 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '11' ),
797 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 176" preserveAspectRatio="none"><path d="M0 0l400 156 400-88 400 74v34H0z"/></svg>',
798 ),
799 'gb-triangle-12' => array(
800 /* translators: Shape number */
801 'label' => sprintf( __( 'Triangle %s', 'generateblocks' ), '12' ),
802 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 176" preserveAspectRatio="none"><path d="M0 176h1200V14L800 88 400 0 0 156z"/></svg>',
803 ),
804 ),
805 ),
806 )
807 );
808 }
809
810 /**
811 * Search an array to check if a key has a value.
812 *
813 * @since 1.5.0
814 * @param string $setting The setting to check.
815 * @param array $data The array to search.
816 */
817 function generateblocks_block_has_value( $setting, $data ) {
818 foreach ( (array) $data as $key => $val ) {
819 if ( isset( $val[ $setting ] ) && ( $val[ $setting ] || 0 === $val[ $setting ] ) ) {
820 return true;
821 }
822 }
823
824 return null;
825 }
826
827 /**
828 * Given an array it will change keys based on the map.
829 *
830 * @param array $arr The array to check.
831 * @param array $keyMap The array to map.
832 *
833 * @return array|false
834 *
835 * @since 1.5.0
836 */
837 function generateblocks_map_array_keys( $arr = array(), $keyMap = array() ) {
838 return array_combine(
839 array_map(
840 function( $key ) use ( $keyMap ) {
841 return isset( $keyMap[ $key ] ) ? $keyMap[ $key ] : $key;
842 },
843 array_keys( $arr )
844 ),
845 array_values( $arr )
846 );
847 }
848
849 /**
850 * Checks if the date is correctly formatted
851 *
852 * @param string $date The date to validate.
853 * @param string $format The allowed format.
854 *
855 * @return bool
856 */
857 function generateblocks_is_valid_date( $date, $format = 'Y-m-d\TH:i:s' ) {
858 $dateTime = DateTime::createFromFormat( $format, $date );
859
860 return ( $dateTime && $dateTime->format( $format ) === $date );
861 }
862
863 /**
864 * Modifies the markup of images in provided content.
865 *
866 * @param string $content The content to modify.
867 * @param array $attributes The block attributes.
868 *
869 * @since 1.5.0
870 */
871 function generateblocks_filter_images( $content, $attributes ) {
872 // Bail early if not using WP 5.5.
873 if ( ! function_exists( 'wp_img_tag_add_width_and_height_attr' ) ) {
874 return $content;
875 }
876
877 if ( ! empty( $attributes['mediaId'] ) ) {
878 // Add 'width' and 'height' attributes if applicable.
879 if ( false === strpos( $content, ' width=' ) && false === strpos( $content, ' height=' ) ) {
880 $content = wp_img_tag_add_width_and_height_attr( $content, '', $attributes['mediaId'] );
881 }
882
883 // Add 'srcset' and 'sizes' attributes if applicable.
884 if ( false === strpos( $content, ' srcset=' ) ) {
885 $content = wp_img_tag_add_srcset_and_sizes_attr( $content, '', $attributes['mediaId'] );
886 }
887 }
888
889 // Add 'loading' attribute if applicable.
890 if ( wp_lazy_loading_enabled( 'img', '' ) && false === strpos( $content, ' loading=' ) ) {
891 $content = wp_img_tag_add_loading_attr( $content, '' );
892 }
893
894 return $content;
895 }
896