PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / trunk
GenerateBlocks vtrunk
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 / blocks / class-container.php
generateblocks / includes / blocks Last commit date
class-block.php 1 year ago class-button-container.php 2 years ago class-button.php 2 years ago class-container.php 2 years ago class-element.php 1 year ago class-grid.php 2 years ago class-headline.php 1 week ago class-image.php 2 years ago class-loop-item.php 1 year ago class-looper.php 1 year ago class-media.php 1 year ago class-query-loop.php 3 years ago class-query-no-results.php 1 year ago class-query-page-numbers.php 1 year ago class-query.php 1 year ago class-shape.php 1 year ago class-text.php 1 year ago
class-container.php
1113 lines
1 <?php
2 /**
3 * Handles the Container block.
4 *
5 * @package GenerateBlocks
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 /**
13 * Add Container related functions.
14 */
15 class GenerateBlocks_Block_Container {
16 /**
17 * Keep track of all blocks of this type on the page.
18 *
19 * @var array $block_ids The current block id.
20 */
21 private static $block_ids = [];
22
23 /**
24 * Keep track of CSS we want to output once per block type.
25 *
26 * @var boolean
27 */
28 private static $singular_css_added = false;
29
30 /**
31 * Block defaults.
32 */
33 public static function defaults() {
34 $container_width = generateblocks_get_option( 'container_width' );
35
36 if ( function_exists( 'generate_get_option' ) ) {
37 $container_width = generate_get_option( 'container_width' );
38 }
39
40 return [
41 'tagName' => 'div',
42 'isGrid' => false,
43 'backgroundColor' => '',
44 'gradient' => false,
45 'gradientDirection' => '',
46 'gradientColorOne' => '',
47 'gradientColorOneOpacity' => '',
48 'gradientColorStopOne' => '',
49 'gradientColorTwo' => '',
50 'gradientColorTwoOpacity' => '',
51 'gradientColorStopTwo' => '',
52 'gradientSelector' => 'element',
53 'textColor' => '',
54 'linkColor' => '',
55 'linkColorHover' => '',
56 'bgImage' => '',
57 'bgOptions' => array(
58 'selector' => 'element',
59 'opacity' => 1,
60 'overlay' => false,
61 'position' => 'center center',
62 'size' => 'cover',
63 'repeat' => 'no-repeat',
64 'attachment' => '',
65 ),
66 'bgImageSize' => 'full',
67 'bgImageInline' => false,
68 'fontFamilyFallback' => '',
69 'googleFont' => false,
70 'googleFontVariants' => '',
71 'useInnerContainer' => false,
72 'variantRole' => '',
73 // Deprecated attributes.
74 'containerWidth' => $container_width,
75 'outerContainer' => 'full',
76 'innerContainer' => 'contained',
77 'minHeight' => false,
78 'minHeightUnit' => 'px',
79 'minHeightTablet' => false,
80 'minHeightUnitTablet' => 'px',
81 'minHeightMobile' => false,
82 'minHeightUnitMobile' => 'px',
83 'width' => '',
84 'widthTablet' => '',
85 'widthMobile' => '',
86 'autoWidth' => false,
87 'autoWidthTablet' => false,
88 'autoWidthMobile' => false,
89 'flexBasisUnit' => 'px',
90 'verticalAlignment' => '',
91 'verticalAlignmentTablet' => 'inherit',
92 'verticalAlignmentMobile' => 'inherit',
93 'borderColorOpacity' => 1,
94 'backgroundColorOpacity' => 1,
95 'fontSize' => '',
96 'fontSizeTablet' => '',
97 'fontSizeMobile' => '',
98 'fontSizeUnit' => 'px',
99 'fontWeight' => '',
100 'textTransform' => '',
101 'alignment' => '',
102 'alignmentTablet' => '',
103 'alignmentMobile' => '',
104 'removeVerticalGap' => false,
105 'removeVerticalGapTablet' => false,
106 'removeVerticalGapMobile' => false,
107 'fontFamily' => '',
108 'borderColor' => '',
109 'innerZindex' => '',
110 ];
111 }
112
113 /**
114 * Store our block ID in memory.
115 *
116 * @param string $id The block ID to store.
117 */
118 public static function store_block_id( $id ) {
119 self::$block_ids[] = $id;
120 }
121
122 /**
123 * Check if our block ID exists.
124 *
125 * @param string $id The block ID to store.
126 */
127 public static function block_id_exists( $id ) {
128 return in_array( $id, (array) self::$block_ids );
129 }
130
131 /**
132 * Compile our CSS data based on our block attributes.
133 *
134 * @param array $attributes Our block attributes.
135 */
136 public static function get_css_data( $attributes ) {
137 $css = new GenerateBlocks_Dynamic_CSS();
138 $desktop_css = new GenerateBlocks_Dynamic_CSS();
139 $tablet_css = new GenerateBlocks_Dynamic_CSS();
140 $tablet_only_css = new GenerateBlocks_Dynamic_CSS();
141 $mobile_css = new GenerateBlocks_Dynamic_CSS();
142 $css_data = [];
143
144 $defaults = generateblocks_get_block_defaults();
145
146 $settings = wp_parse_args(
147 $attributes,
148 $defaults['container']
149 );
150
151 $id = $attributes['uniqueId'];
152 $blockVersion = ! empty( $settings['blockVersion'] ) ? $settings['blockVersion'] : 1;
153
154 // Use legacy settings if needed.
155 if ( $blockVersion < 2 ) {
156 $settings = GenerateBlocks_Legacy_Attributes::get_settings( '1.4.0', 'container', $settings, $attributes );
157 }
158
159 // Map deprecated settings.
160 $settings = GenerateBlocks_Map_Deprecated_Attributes::map_attributes( $settings );
161
162 $selector = generateblocks_get_css_selector( 'container', $attributes );
163 $use_visited_selector = generateblocks_use_visited_selector( 'container', $attributes );
164 $settings['useInnerContainer'] = $blockVersion < 3 || $settings['useInnerContainer'];
165 $useInnerContainer = $settings['useInnerContainer'];
166
167 if ( ! isset( $settings['bgOptions']['selector'] ) ) {
168 $settings['bgOptions']['selector'] = 'element';
169 }
170
171 $containerWidth = $settings['containerWidth'];
172
173 if ( isset( $settings['useGlobalStyle'] ) && $settings['useGlobalStyle'] ) {
174 if ( (string) $containerWidth === (string) $defaults['container']['containerWidth'] ) {
175 $containerWidth = '';
176 }
177 }
178
179 $backgroundImageValue = generateblocks_get_background_image_css( 'image', $settings );
180 $gradientValue = generateblocks_get_background_image_css( 'gradient', $settings );
181 $hasBgImage = generateblocks_has_background_image( $settings );
182
183 // Only add this CSS once.
184 if ( ! self::$singular_css_added ) {
185 do_action(
186 'generateblocks_block_one_time_css_data',
187 'container',
188 $settings,
189 $css
190 );
191
192 self::$singular_css_added = true;
193 }
194
195 /**
196 * Main Container selector.
197 *
198 * Example: .gb-container-{ $uniqueId }
199 */
200 $css->set_selector( $selector );
201 generateblocks_add_sizing_css( $css, $settings );
202 generateblocks_add_layout_css( $css, $settings );
203 generateblocks_add_flex_child_css( $css, $settings );
204 generateblocks_add_typography_css( $css, $settings );
205 generateblocks_add_spacing_css( $css, $settings );
206 generateblocks_add_border_css( $css, $settings );
207 $css->add_property( 'background-color', generateblocks_hex2rgba( $settings['backgroundColor'], $settings['backgroundColorOpacity'] ) );
208 $css->add_property( 'color', $settings['textColor'] );
209
210 if ( $hasBgImage && 'element' === $settings['bgOptions']['selector'] && $backgroundImageValue ) {
211 if ( ! $settings['bgImageInline'] || ( $settings['bgImageInline'] && 'element' !== $settings['bgOptions']['selector'] ) ) {
212 $css->add_property( 'background-image', $backgroundImageValue );
213 }
214
215 $css->add_property( 'background-repeat', $settings['bgOptions']['repeat'] );
216 $css->add_property( 'background-position', $settings['bgOptions']['position'] );
217 $css->add_property( 'background-size', $settings['bgOptions']['size'] );
218 $css->add_property( 'background-attachment', $settings['bgOptions']['attachment'] );
219 } elseif ( $settings['gradient'] && 'element' === $settings['gradientSelector'] ) {
220 $css->add_property( 'background-image', $gradientValue );
221 }
222
223 if ( $useInnerContainer ) {
224 if (
225 ( $hasBgImage && 'pseudo-element' === $settings['bgOptions']['selector'] ) ||
226 $settings['zindex'] ||
227 ( $settings['gradient'] && 'pseudo-element' === $settings['gradientSelector'] )
228 ) {
229 $css->add_property( 'position', 'relative' );
230 }
231
232 if (
233 ( $hasBgImage && 'pseudo-element' === $settings['bgOptions']['selector'] ) ||
234 ( $settings['gradient'] && 'pseudo-element' === $settings['gradientSelector'] )
235 ) {
236 $css->add_property( 'overflow', 'hidden' );
237 }
238 }
239
240 if ( $blockVersion < 3 ) {
241 $css->add_property( 'min-height', $settings['minHeight'], $settings['minHeightUnit'] );
242 }
243
244 // Set flags so we don't duplicate this CSS in media queries.
245 $usingMinHeightFlex = false;
246 $usingMinHeightInnerWidth = false;
247
248 if ( $useInnerContainer ) {
249 if ( $settings['zindex'] ) {
250 $css->add_property( 'z-index', $settings['zindex'] );
251 }
252
253 if ( 'contained' === $settings['outerContainer'] && ! $settings['isGrid'] ) {
254 if ( ! empty( $containerWidth ) ) {
255 $css->add_property( 'max-width', absint( $containerWidth ), 'px' );
256 $css->add_property( 'margin-left', 'auto' );
257 $css->add_property( 'margin-right', 'auto' );
258 }
259 }
260
261 $minHeight = $blockVersion < 3 ? $settings['minHeight'] : generateblocks_get_array_attribute_value( 'minHeight', $settings['sizing'] );
262
263 if ( $minHeight && $settings['verticalAlignment'] && ! $settings['isGrid'] ) {
264 $css->add_property( 'display', 'flex' );
265 $css->add_property( 'flex-direction', 'row' );
266 $css->add_property( 'align-items', $settings['verticalAlignment'] );
267
268 $usingMinHeightFlex = true;
269 }
270 }
271
272 $innerZIndex = $settings['innerZindex'];
273
274 /**
275 * Container before pseudo selector.
276 *
277 * Example: .gb-container-{ $uniqueId }:before
278 */
279 $css->set_selector( $selector . ':before' );
280
281 if ( $hasBgImage && 'pseudo-element' === $settings['bgOptions']['selector'] ) {
282 $css->add_property( 'content', '""' );
283 $css->add_property( 'background-image', $backgroundImageValue );
284 $css->add_property( 'background-repeat', $settings['bgOptions']['repeat'] );
285 $css->add_property( 'background-position', $settings['bgOptions']['position'] );
286 $css->add_property( 'background-size', $settings['bgOptions']['size'] );
287 $css->add_property( 'background-attachment', $settings['bgOptions']['attachment'] );
288 $css->add_property( 'z-index', '0' );
289 $css->add_property( 'position', 'absolute' );
290 $css->add_property( 'top', '0' );
291 $css->add_property( 'right', '0' );
292 $css->add_property( 'bottom', '0' );
293 $css->add_property( 'left', '0' );
294 $css->add_property( 'transition', 'inherit' );
295 $css->add_property(
296 'border-radius',
297 array(
298 generateblocks_get_array_attribute_value( 'borderTopLeftRadius', $settings['borders'] ),
299 generateblocks_get_array_attribute_value( 'borderTopRightRadius', $settings['borders'] ),
300 generateblocks_get_array_attribute_value( 'borderBottomRightRadius', $settings['borders'] ),
301 generateblocks_get_array_attribute_value( 'borderBottomLeftRadius', $settings['borders'] ),
302 )
303 );
304 $css->add_property( 'pointer-events', 'none' );
305
306 if ( isset( $settings['bgOptions']['opacity'] ) && 1 !== $settings['bgOptions']['opacity'] ) {
307 $css->add_property( 'opacity', $settings['bgOptions']['opacity'] );
308 }
309
310 if ( $blockVersion < 2 && ! $innerZIndex ) {
311 $innerZIndex = 1;
312 }
313 }
314
315 /**
316 * Container after pseudo selector.
317 *
318 * Example: .gb-container-{ $uniqueId }:after
319 */
320 if ( $settings['gradient'] && 'pseudo-element' === $settings['gradientSelector'] ) {
321 $css->set_selector( $selector . ':after' );
322 $css->add_property( 'content', '""' );
323 $css->add_property( 'background-image', $gradientValue );
324 $css->add_property( 'z-index', '0' );
325 $css->add_property( 'position', 'absolute' );
326 $css->add_property( 'top', '0' );
327 $css->add_property( 'right', '0' );
328 $css->add_property( 'bottom', '0' );
329 $css->add_property( 'left', '0' );
330 $css->add_property( 'pointer-events', 'none' );
331
332 if ( $blockVersion < 2 && ! $innerZIndex ) {
333 $innerZIndex = 1;
334 }
335 }
336
337 /**
338 * Legacy inner Container selector.
339 *
340 * Example: .gb-container-{ $uniqueId } > .gb-inside-container
341 */
342 if ( $useInnerContainer ) {
343 $css->set_selector( $selector . ' > .gb-inside-container' );
344 if ( $blockVersion < 4 ) {
345 $css->add_property( 'padding', array( $settings['paddingTop'], $settings['paddingRight'], $settings['paddingBottom'], $settings['paddingLeft'] ), $settings['paddingUnit'] );
346 } else {
347 $css->add_property(
348 'padding',
349 array(
350 generateblocks_get_array_attribute_value( 'paddingTop', $settings['spacing'] ),
351 generateblocks_get_array_attribute_value( 'paddingRight', $settings['spacing'] ),
352 generateblocks_get_array_attribute_value( 'paddingBottom', $settings['spacing'] ),
353 generateblocks_get_array_attribute_value( 'paddingLeft', $settings['spacing'] ),
354 )
355 );
356 }
357
358 if ( 'contained' === $settings['innerContainer'] && ! $settings['isGrid'] ) {
359 if ( ! empty( $containerWidth ) ) {
360 $css->add_property( 'max-width', absint( $containerWidth ), 'px' );
361 $css->add_property( 'margin-left', 'auto' );
362 $css->add_property( 'margin-right', 'auto' );
363 }
364 }
365
366 if ( $usingMinHeightFlex ) {
367 $css->add_property( 'width', '100%' );
368
369 $usingMinHeightInnerWidth = true;
370 }
371
372 if ( $innerZIndex || 0 === $innerZIndex ) {
373 $css->add_property( 'z-index', $innerZIndex );
374 $css->add_property( 'position', 'relative' );
375 }
376 }
377
378 /**
379 * Container hover.
380 *
381 * Example: .gb-container-{ $uniqueId }:hover
382 */
383 $css->set_selector( $selector . ':hover' );
384 generateblocks_add_border_color_css( $css, $settings, 'Hover' );
385
386 /**
387 * Container current.
388 *
389 * Example: .gb-container-{ $uniqueId }.gb-block-is-current
390 */
391 $current_selector = sprintf(
392 '%1$s.gb-block-is-current, %1$s.gb-block-is-current:hover, %1$s.gb-block-is-current:active, %1$s.gb-block-is-current:focus',
393 $selector
394 );
395
396 $css->set_selector( $current_selector );
397 generateblocks_add_border_color_css( $css, $settings, 'Current' );
398
399 /**
400 * Container links.
401 *
402 * Example: .gb-container-{ $uniqueId } a
403 */
404 $visited_selector = $use_visited_selector
405 ? ', ' . $selector . ' a:visited'
406 : '';
407
408 $css->set_selector( $selector . ' a' . $visited_selector );
409 $css->add_property( 'color', $settings['linkColor'] );
410
411 $css->set_selector( $selector . ' a:hover' );
412 $css->add_property( 'color', $settings['linkColorHover'] );
413
414 /**
415 * Grid item selector.
416 *
417 * Example: .gb-grid-wrapper > .gb-grid-column-{ $uniqueId }
418 */
419 if ( $settings['isGrid'] ) {
420 $css->set_selector( '.gb-grid-wrapper > .gb-grid-column-' . $id );
421
422 if ( $blockVersion < 3 ) {
423 $css->add_property( 'width', $settings['width'], '%' );
424 } else {
425 $css->add_property( 'width', generateblocks_get_array_attribute_value( 'width', $settings['sizing'] ) );
426 }
427
428 $css->add_property( 'flex-grow', $settings['flexGrow'] );
429 $css->add_property( 'flex-shrink', $settings['flexShrink'] );
430
431 if ( is_numeric( $settings['flexBasis'] ) && $blockVersion < 3 ) {
432 $css->add_property( 'flex-basis', $settings['flexBasis'], $settings['flexBasisUnit'] );
433 } else {
434 $css->add_property( 'flex-basis', $settings['flexBasis'] );
435 }
436
437 if ( $settings['isGrid'] ) {
438 $css->add_property( 'order', $settings['order'] );
439 }
440 }
441
442 /**
443 * Grid item selector with tag name.
444 *
445 * This was used for the removeVerticalGap option which was deprecated
446 * in version 3 of the Grid block.
447 *
448 * Example: .gb-grid-wrapper > div.gb-grid-column-{ $uniqueId }
449 */
450 if ( $settings['removeVerticalGap'] ) {
451 $desktop_css->set_selector( '.gb-grid-wrapper > div.gb-grid-column-' . $id );
452 $desktop_css->add_property( 'padding-bottom', '0' );
453 }
454
455 /**
456 * Grid item Container selector.
457 *
458 * Example: .gb-grid-wrapper > .gb-grid-column-{ $uniqueId } > .gb-container
459 */
460 if ( $useInnerContainer ) {
461 $css->set_selector( '.gb-grid-wrapper > .gb-grid-column-' . $id . ' > .gb-container' );
462 $css->add_property( 'justify-content', $settings['verticalAlignment'] );
463 $css->add_property( 'display', 'flex' );
464 $css->add_property( 'flex-direction', 'column' );
465 $css->add_property( 'height', '100%' );
466 }
467
468 /**
469 * Container selector for shapes.
470 *
471 * Example: .gb-container-{ $uniqueId }
472 */
473 if ( ! empty( $settings['shapeDividers'] ) ) {
474 $css->set_selector( $selector );
475
476 if ( $useInnerContainer ) {
477 $css->add_property( 'position', 'relative' );
478 }
479
480 $default_styles = generateblocks_get_default_styles();
481
482 foreach ( (array) $settings['shapeDividers'] as $index => $options ) {
483 $shapeNumber = $index + 1;
484
485 $shapeOptions = wp_parse_args(
486 $options,
487 $default_styles['container']['shapeDividers']
488 );
489
490 $shapeTransforms = array();
491
492 if ( 'top' === $shapeOptions['location'] ) {
493 $shapeTransforms[] = 'scaleY(-1)';
494 }
495
496 if ( $shapeOptions['flipHorizontally'] ) {
497 $shapeTransforms[] = 'scaleX(-1)';
498 }
499
500 $css->set_selector( $selector . ' > .gb-shapes .gb-shape-' . $shapeNumber );
501 $css->add_property( 'color', generateblocks_hex2rgba( $shapeOptions['color'], $shapeOptions['colorOpacity'] ) );
502 $css->add_property( 'z-index', $shapeOptions['zindex'] );
503 $css->add_property( 'position', 'absolute' );
504 $css->add_property( 'overflow', 'hidden' );
505 $css->add_property( 'pointer-events', 'none' );
506 $css->add_property( 'line-height', '0' );
507
508 if ( 'top' === $shapeOptions['location'] || 'bottom' === $shapeOptions['location'] ) {
509 $css->add_property( 'left', '0' );
510 $css->add_property( 'right', '0' );
511 }
512
513 if ( 'bottom' === $shapeOptions['location'] ) {
514 $css->add_property( 'bottom', '-1px' );
515 }
516
517 if ( 'top' === $shapeOptions['location'] ) {
518 $css->add_property( 'top', '-1px' );
519 }
520
521 if ( ! empty( $shapeTransforms ) ) {
522 $css->add_property( 'transform', implode( ' ', $shapeTransforms ) );
523 }
524
525 $shapeWidth = $shapeOptions['width'] . '%';
526
527 if ( 100 === (int) $shapeOptions['width'] ) {
528 $shapeWidth = 'calc(' . $shapeWidth . ' + 1.3px)';
529 }
530
531 $css->set_selector( $selector . ' > .gb-shapes .gb-shape-' . $shapeNumber . ' svg' );
532 $css->add_property( 'height', $shapeOptions['height'], 'px' );
533 $css->add_property( 'width', $shapeWidth );
534 $css->add_property( 'fill', 'currentColor' );
535
536 if ( 'top' === $shapeOptions['location'] || 'bottom' === $shapeOptions['location'] ) {
537 $css->add_property( 'position', 'relative' );
538 $css->add_property( 'left', '50%' );
539 $css->add_property( 'transform', 'translateX(-50%)' );
540 $css->add_property( 'min-width', '100%' );
541 }
542 }
543 }
544
545 /**
546 * Main Container selector for tablet.
547 *
548 * Example: .gb-container-{ $uniqueId }
549 */
550 $tablet_css->set_selector( $selector );
551 generateblocks_add_sizing_css( $tablet_css, $settings, 'Tablet' );
552 generateblocks_add_layout_css( $tablet_css, $settings, 'Tablet' );
553 generateblocks_add_flex_child_css( $tablet_css, $settings, 'Tablet' );
554 generateblocks_add_typography_css( $tablet_css, $settings, 'Tablet' );
555 generateblocks_add_spacing_css( $tablet_css, $settings, 'Tablet' );
556 generateblocks_add_border_css( $tablet_css, $settings, 'Tablet' );
557
558 if ( $blockVersion < 3 ) {
559 $tablet_css->add_property( 'min-height', $settings['minHeightTablet'], $settings['minHeightUnitTablet'] );
560 }
561
562 if ( $useInnerContainer ) {
563 // Need to check if we're using minHeightTablet in two places below.
564 $minHeightTablet = $blockVersion < 3 ? $settings['minHeightTablet'] : generateblocks_get_array_attribute_value( 'minHeightTablet', $settings['sizing'] );
565
566 if ( ! $settings['isGrid'] ) {
567 if ( ! $usingMinHeightFlex && $minHeightTablet && 'inherit' !== $settings['verticalAlignmentTablet'] ) {
568 $tablet_css->add_property( 'display', 'flex' );
569 $tablet_css->add_property( 'flex-direction', 'row' );
570
571 $usingMinHeightFlex = true;
572 }
573
574 if ( $usingMinHeightFlex && 'inherit' !== $settings['verticalAlignmentTablet'] ) {
575 $tablet_css->add_property( 'align-items', $settings['verticalAlignmentTablet'] );
576 }
577 }
578
579 /**
580 * Legacy inner Container selector for tablet.
581 *
582 * Example: .gb-container-{ $uniqueId } > .gb-inside-container
583 */
584 $tablet_css->set_selector( $selector . ' > .gb-inside-container' );
585
586 if ( $blockVersion < 4 ) {
587 $tablet_css->add_property( 'padding', array( $settings['paddingTopTablet'], $settings['paddingRightTablet'], $settings['paddingBottomTablet'], $settings['paddingLeftTablet'] ), $settings['paddingUnit'] );
588 } else {
589 $tablet_css->add_property(
590 'padding',
591 array(
592 generateblocks_get_array_attribute_value( 'paddingTopTablet', $settings['spacing'] ),
593 generateblocks_get_array_attribute_value( 'paddingRightTablet', $settings['spacing'] ),
594 generateblocks_get_array_attribute_value( 'paddingBottomTablet', $settings['spacing'] ),
595 generateblocks_get_array_attribute_value( 'paddingLeftTablet', $settings['spacing'] ),
596 )
597 );
598 }
599
600 $usingMinHeightInnerWidthBoxSizing = false;
601
602 if ( ! $settings['isGrid'] ) {
603 // Needs 100% width if it's a flex item.
604 if ( ! $usingMinHeightInnerWidth && $minHeightTablet && 'inherit' !== $settings['verticalAlignmentTablet'] ) {
605 $tablet_css->add_property( 'width', '100%' );
606
607 $usingMinHeightInnerWidth = true;
608 } elseif ( $usingMinHeightInnerWidth ) {
609 if ( 'contained' === $settings['innerContainer'] && ! $settings['isGrid'] ) {
610 $tablet_css->add_property( 'box-sizing', 'border-box' );
611
612 $usingMinHeightInnerWidthBoxSizing = true;
613 }
614 }
615 }
616 }
617
618 /**
619 * Grid item selector for tablet.
620 *
621 * Example: .gb-grid-wrapper > .gb-grid-column-{ $uniqueId }
622 */
623 $tablet_css->set_selector( '.gb-grid-wrapper > .gb-grid-column-' . $id );
624
625 if ( $blockVersion < 3 ) {
626 if ( ! $settings['autoWidthTablet'] ) {
627 $tablet_css->add_property( 'width', $settings['widthTablet'], '%' );
628 } else {
629 $tablet_css->add_property( 'width', 'auto' );
630 }
631 } else {
632 $tablet_css->add_property( 'width', generateblocks_get_array_attribute_value( 'widthTablet', $settings['sizing'] ) );
633 }
634
635 $tablet_css->add_property( 'flex-grow', $settings['flexGrowTablet'] );
636 $tablet_css->add_property( 'flex-shrink', $settings['flexShrinkTablet'] );
637
638 if ( is_numeric( $settings['flexBasisTablet'] ) ) {
639 $tablet_css->add_property( 'flex-basis', $settings['flexBasisTablet'], $settings['flexBasisUnit'] );
640 } else {
641 $tablet_css->add_property( 'flex-basis', $settings['flexBasisTablet'] );
642 }
643
644 if ( $settings['isGrid'] ) {
645 $tablet_css->add_property( 'order', $settings['orderTablet'] );
646 }
647
648 /**
649 * Grid item selector with tag name for tablet.
650 *
651 * This was used for the removeVerticalGap option which was deprecated
652 * in version 3 of the Grid block.
653 *
654 * Example: .gb-grid-wrapper > div.gb-grid-column-{ $uniqueId }
655 */
656 if ( $settings['removeVerticalGapTablet'] ) {
657 $tablet_only_css->set_selector( '.gb-grid-wrapper > div.gb-grid-column-' . $id );
658 $tablet_only_css->add_property( 'padding-bottom', '0' );
659 }
660
661 /**
662 * Grid item Container selector for tablet.
663 *
664 * Example: .gb-grid-wrapper > .gb-grid-column-{ $uniqueId } > .gb-container
665 */
666 if ( $useInnerContainer ) {
667 $tablet_css->set_selector( '.gb-grid-wrapper > .gb-grid-column-' . $id . ' > .gb-container' );
668
669 if ( 'inherit' !== $settings['verticalAlignmentTablet'] ) {
670 $tablet_css->add_property( 'justify-content', $settings['verticalAlignmentTablet'] );
671 }
672 }
673
674 /**
675 * Container before pseudo selector for tablet.
676 *
677 * Example: .gb-container-{ $uniqueId }:before
678 */
679 if ( $hasBgImage && 'pseudo-element' === $settings['bgOptions']['selector'] ) {
680 $tablet_css->set_selector( $selector . ':before' );
681 $tablet_css->add_property(
682 'border-radius',
683 array(
684 generateblocks_get_array_attribute_value( 'borderTopLeftRadiusTablet', $settings['borders'] ),
685 generateblocks_get_array_attribute_value( 'borderTopRightRadiusTablet', $settings['borders'] ),
686 generateblocks_get_array_attribute_value( 'borderBottomRightRadiusTablet', $settings['borders'] ),
687 generateblocks_get_array_attribute_value( 'borderBottomLeftRadiusTablet', $settings['borders'] ),
688 )
689 );
690 }
691
692 /**
693 * Shape selector for tablets.
694 *
695 * Example: .gb-container-{ $uniqueId } > .gb-shapes .gb-shape-{ $shapeNumber } svg
696 */
697 if ( ! empty( $settings['shapeDividers'] ) ) {
698 $default_styles = generateblocks_get_default_styles();
699
700 foreach ( (array) $settings['shapeDividers'] as $index => $options ) {
701 $shapeNumber = $index + 1;
702
703 $shapeOptions = wp_parse_args(
704 $options,
705 $default_styles['container']['shapeDividers']
706 );
707
708 $tablet_css->set_selector( $selector . ' > .gb-shapes .gb-shape-' . $shapeNumber . ' svg' );
709 $tablet_css->add_property( 'height', $shapeOptions['heightTablet'], 'px' );
710 $tablet_css->add_property( 'width', $shapeOptions['widthTablet'], '%' );
711 }
712 }
713
714 /**
715 * Main Container selector for mobile.
716 *
717 * Example: .gb-container-{ $uniqueId }
718 */
719 $mobile_css->set_selector( $selector );
720 generateblocks_add_sizing_css( $mobile_css, $settings, 'Mobile' );
721 generateblocks_add_layout_css( $mobile_css, $settings, 'Mobile' );
722 generateblocks_add_flex_child_css( $mobile_css, $settings, 'Mobile' );
723 generateblocks_add_typography_css( $mobile_css, $settings, 'Mobile' );
724 generateblocks_add_spacing_css( $mobile_css, $settings, 'Mobile' );
725 generateblocks_add_border_css( $mobile_css, $settings, 'Mobile' );
726
727 if ( $blockVersion < 3 ) {
728 $mobile_css->add_property( 'min-height', $settings['minHeightMobile'], $settings['minHeightUnitMobile'] );
729 }
730
731 if ( $useInnerContainer ) {
732 // Need to check if we're using minHeightMobile in two places below.
733 $minHeightMobile = $blockVersion < 3 ? $settings['minHeightMobile'] : generateblocks_get_array_attribute_value( 'minHeightMobile', $settings['sizing'] );
734
735 if ( ! $settings['isGrid'] ) {
736 if ( ! $usingMinHeightFlex && $minHeightMobile && 'inherit' !== $settings['verticalAlignmentMobile'] ) {
737 $mobile_css->add_property( 'display', 'flex' );
738 $mobile_css->add_property( 'flex-direction', 'row' );
739
740 $usingMinHeightFlex = true;
741 }
742
743 if ( $usingMinHeightFlex && 'inherit' !== $settings['verticalAlignmentMobile'] ) {
744 $mobile_css->add_property( 'align-items', $settings['verticalAlignmentMobile'] );
745 }
746 }
747
748 /**
749 * Legacy inner Container selector for mobile.
750 *
751 * Example: .gb-container-{ $uniqueId } > .gb-inside-container
752 */
753 $mobile_css->set_selector( $selector . ' > .gb-inside-container' );
754
755 if ( $blockVersion < 4 ) {
756 $mobile_css->add_property( 'padding', array( $settings['paddingTopMobile'], $settings['paddingRightMobile'], $settings['paddingBottomMobile'], $settings['paddingLeftMobile'] ), $settings['paddingUnit'] );
757 } else {
758 $mobile_css->add_property(
759 'padding',
760 array(
761 generateblocks_get_array_attribute_value( 'paddingTopMobile', $settings['spacing'] ),
762 generateblocks_get_array_attribute_value( 'paddingRightMobile', $settings['spacing'] ),
763 generateblocks_get_array_attribute_value( 'paddingBottomMobile', $settings['spacing'] ),
764 generateblocks_get_array_attribute_value( 'paddingLeftMobile', $settings['spacing'] ),
765 )
766 );
767 }
768
769 if ( ! $settings['isGrid'] ) {
770 // Needs 100% width if it's a flex item.
771 if ( ! $usingMinHeightInnerWidth && $minHeightMobile && 'inherit' !== $settings['verticalAlignmentMobile'] ) {
772 $mobile_css->add_property( 'width', '100%' );
773 } elseif ( $usingMinHeightInnerWidth && ! $usingMinHeightInnerWidthBoxSizing ) {
774 if ( 'contained' === $settings['innerContainer'] && ! $settings['isGrid'] ) {
775 $mobile_css->add_property( 'box-sizing', 'border-box' );
776 }
777 }
778 }
779 }
780
781 /**
782 * Grid item selector for tablet.
783 *
784 * Example: .gb-grid-wrapper > .gb-grid-column-{ $uniqueId }
785 */
786 $mobile_css->set_selector( '.gb-grid-wrapper > .gb-grid-column-' . $id );
787
788 if ( $blockVersion < 3 ) {
789 if ( ! $settings['autoWidthMobile'] ) {
790 $mobile_css->add_property( 'width', $settings['widthMobile'], '%' );
791 }
792
793 if ( $settings['autoWidthMobile'] ) {
794 $mobile_css->add_property( 'width', 'auto' );
795 }
796 } else {
797 $mobile_css->add_property( 'width', generateblocks_get_array_attribute_value( 'widthMobile', $settings['sizing'] ) );
798 }
799
800 $mobile_css->add_property( 'flex-grow', $settings['flexGrowMobile'] );
801 $mobile_css->add_property( 'flex-shrink', $settings['flexShrinkMobile'] );
802
803 if ( is_numeric( $settings['flexBasisMobile'] ) ) {
804 $mobile_css->add_property( 'flex-basis', $settings['flexBasisMobile'], $settings['flexBasisUnit'] );
805 } else {
806 $mobile_css->add_property( 'flex-basis', $settings['flexBasisMobile'] );
807 }
808
809 if ( $settings['isGrid'] ) {
810 $mobile_css->add_property( 'order', $settings['orderMobile'] );
811 }
812
813 /**
814 * Grid item selector with tag name for mobile.
815 *
816 * This was used for the removeVerticalGap option which was deprecated
817 * in version 3 of the Grid block.
818 *
819 * Example: .gb-grid-wrapper > div.gb-grid-column-{ $uniqueId }
820 */
821 if ( $settings['removeVerticalGapMobile'] ) {
822 $mobile_css->set_selector( '.gb-grid-wrapper > div.gb-grid-column-' . $id );
823 $mobile_css->add_property( 'padding-bottom', '0' );
824 }
825
826 /**
827 * Grid item Container selector for mobile.
828 *
829 * Example: .gb-grid-wrapper > .gb-grid-column-{ $uniqueId } > .gb-container
830 */
831 if ( $useInnerContainer ) {
832 $mobile_css->set_selector( '.gb-grid-wrapper > .gb-grid-column-' . $id . ' > .gb-container' );
833
834 if ( 'inherit' !== $settings['verticalAlignmentMobile'] ) {
835 $mobile_css->add_property( 'justify-content', $settings['verticalAlignmentMobile'] );
836 }
837 }
838
839 /**
840 * Container before pseudo selector for mobile.
841 *
842 * Example: .gb-container-{ $uniqueId }:before
843 */
844 if ( $hasBgImage && 'pseudo-element' === $settings['bgOptions']['selector'] ) {
845 $mobile_css->set_selector( $selector . ':before' );
846 $mobile_css->add_property(
847 'border-radius',
848 array(
849 generateblocks_get_array_attribute_value( 'borderTopLeftRadiusMobile', $settings['borders'] ),
850 generateblocks_get_array_attribute_value( 'borderTopRightRadiusMobile', $settings['borders'] ),
851 generateblocks_get_array_attribute_value( 'borderBottomRightRadiusMobile', $settings['borders'] ),
852 generateblocks_get_array_attribute_value( 'borderBottomLeftRadiusMobile', $settings['borders'] ),
853 )
854 );
855 }
856
857 /**
858 * Shape selector for tablets.
859 *
860 * Example: .gb-container-{ $uniqueId } > .gb-shapes .gb-shape-{ $shapeNumber } svg
861 */
862 if ( ! empty( $settings['shapeDividers'] ) ) {
863 $default_styles = generateblocks_get_default_styles();
864
865 foreach ( (array) $settings['shapeDividers'] as $index => $options ) {
866 $shapeNumber = $index + 1;
867
868 $shapeOptions = wp_parse_args(
869 $options,
870 $default_styles['container']['shapeDividers']
871 );
872
873 $mobile_css->set_selector( $selector . ' > .gb-shapes .gb-shape-' . $shapeNumber . ' svg' );
874 $mobile_css->add_property( 'height', $shapeOptions['heightMobile'], 'px' );
875 $mobile_css->add_property( 'width', $shapeOptions['widthMobile'], '%' );
876 }
877 }
878
879 /**
880 * Conditional selector to disable fixed backgrounds on mobile.
881 *
882 * Example 1: .gb-container-{ $uniqueId }
883 * Example 2: .gb-container-{ $uniqueId }:before
884 */
885 if ( $hasBgImage && 'fixed' === $settings['bgOptions']['attachment'] ) {
886 if ( 'element' === $settings['bgOptions']['selector'] ) {
887 $mobile_css->set_selector( $selector );
888 }
889
890 if ( 'pseudo-element' === $settings['bgOptions']['selector'] ) {
891 $mobile_css->set_selector( $selector . ':before' );
892 }
893
894 $mobile_css->add_property( 'background-attachment', 'initial' );
895 }
896
897 // Store this block ID in memory.
898 self::store_block_id( $id );
899
900 /**
901 * Do generateblocks_block_css_data hook
902 *
903 * @since 1.0
904 *
905 * @param string $name The name of our block.
906 * @param array $settings The settings for the current block.
907 * @param object $css Our desktop/main CSS data.
908 * @param object $desktop_css Our desktop only CSS data.
909 * @param object $tablet_css Our tablet CSS data.
910 * @param object $tablet_only_css Our tablet only CSS data.
911 * @param object $mobile_css Our mobile CSS data.
912 */
913 do_action(
914 'generateblocks_block_css_data',
915 'container',
916 $settings,
917 $css,
918 $desktop_css,
919 $tablet_css,
920 $tablet_only_css,
921 $mobile_css
922 );
923
924 return [
925 'main' => $css->css_output(),
926 'desktop' => $desktop_css->css_output(),
927 'tablet' => $tablet_css->css_output(),
928 'tablet_only' => $tablet_only_css->css_output(),
929 'mobile' => $mobile_css->css_output(),
930 ];
931 }
932
933 /**
934 * Wrapper function for our dynamic buttons.
935 *
936 * @since 1.6.0
937 * @param array $attributes The block attributes.
938 * @param string $content The dynamic text to display.
939 * @param WP_Block $block Block instance.
940 */
941 public static function render_block( $attributes, $content, $block ) {
942 if ( ! isset( $attributes['isDynamic'] ) || ! $attributes['isDynamic'] ) {
943 // Add styles to this block if needed.
944 $content = generateblocks_maybe_add_block_css(
945 $content,
946 [
947 'class_name' => 'GenerateBlocks_Block_Container',
948 'attributes' => $attributes,
949 'block_ids' => self::$block_ids,
950 ]
951 );
952
953 return $content;
954 }
955
956 $defaults = generateblocks_get_block_defaults();
957
958 $settings = wp_parse_args(
959 $attributes,
960 $defaults['container']
961 );
962
963 $blockVersion = ! empty( $settings['blockVersion'] ) ? $settings['blockVersion'] : 1;
964 $useInnerContainer = $blockVersion < 3 || $settings['useInnerContainer'];
965
966 // Add styles to this block if needed.
967 $output = generateblocks_maybe_add_block_css(
968 '',
969 [
970 'class_name' => 'GenerateBlocks_Block_Container',
971 'attributes' => $attributes,
972 'block_ids' => self::$block_ids,
973 ]
974 );
975
976 if ( $settings['isGrid'] ) {
977 $gridItemClassNames = array(
978 'gb-grid-column',
979 'gb-grid-column-' . $settings['uniqueId'],
980 );
981
982 $output .= sprintf(
983 '<div %s>',
984 generateblocks_attr(
985 'grid-item',
986 array(
987 'class' => implode( ' ', $gridItemClassNames ),
988 ),
989 $settings,
990 $block
991 )
992 );
993 }
994
995 $classNames = array(
996 'gb-container',
997 'gb-container-' . $settings['uniqueId'],
998 );
999
1000 if ( ! empty( $settings['className'] ) ) {
1001 $classNames[] = $settings['className'];
1002 }
1003
1004 if ( ! $settings['isGrid'] && ! empty( $settings['align'] ) ) {
1005 $classNames[] = 'align' . $settings['align'];
1006 }
1007
1008 // Pass the dynamic url to our URL attribute.
1009 if ( isset( $settings['url'] ) ) {
1010 if ( $settings['useDynamicData'] && '' !== $settings['dynamicLinkType'] ) {
1011 $attributes['url'] = GenerateBlocks_Dynamic_Content::get_dynamic_url( $settings, $block );
1012 $settings['url'] = $attributes['url'];
1013 }
1014 }
1015
1016 $tagName = apply_filters(
1017 'generateblocks_container_tagname',
1018 $settings['tagName'],
1019 $attributes,
1020 $block
1021 );
1022
1023 $allowedTagNames = apply_filters(
1024 'generateblocks_container_allowed_tagnames',
1025 array(
1026 'div',
1027 'article',
1028 'section',
1029 'header',
1030 'footer',
1031 'aside',
1032 'a',
1033 ),
1034 $attributes,
1035 $block
1036 );
1037
1038 if ( ! in_array( $tagName, $allowedTagNames ) ) {
1039 $tagName = 'div';
1040 }
1041
1042 $output = apply_filters(
1043 'generateblocks_before_container_open',
1044 $output,
1045 $attributes,
1046 $block
1047 );
1048
1049 $output .= sprintf(
1050 '<%1$s %2$s>',
1051 $tagName,
1052 generateblocks_attr(
1053 'container',
1054 array(
1055 'id' => isset( $settings['anchor'] ) ? $settings['anchor'] : null,
1056 'class' => implode( ' ', $classNames ),
1057 ),
1058 $settings,
1059 $block
1060 )
1061 );
1062
1063 $output = apply_filters(
1064 'generateblocks_after_container_open',
1065 $output,
1066 $attributes,
1067 $block
1068 );
1069
1070 if ( $useInnerContainer ) {
1071 $output .= '<div class="gb-inside-container">';
1072 }
1073
1074 $output = apply_filters(
1075 'generateblocks_inside_container',
1076 $output,
1077 $attributes,
1078 $block
1079 );
1080
1081 $output .= $content;
1082
1083 if ( $useInnerContainer ) {
1084 $output .= '</div>';
1085 }
1086
1087 $output = apply_filters(
1088 'generateblocks_before_container_close',
1089 $output,
1090 $attributes,
1091 $block
1092 );
1093
1094 $output .= sprintf(
1095 '</%s>',
1096 $tagName
1097 );
1098
1099 $output = apply_filters(
1100 'generateblocks_after_container_close',
1101 $output,
1102 $attributes,
1103 $block
1104 );
1105
1106 if ( $settings['isGrid'] ) {
1107 $output .= '</div>';
1108 }
1109
1110 return $output;
1111 }
1112 }
1113