PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.8.0
GenerateBlocks v1.8.0
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-button.php
generateblocks / includes / blocks Last commit date
class-button-container.php 2 years ago class-button.php 2 years ago class-container.php 2 years ago class-grid.php 3 years ago class-headline.php 2 years ago class-image.php 2 years ago class-query-loop.php 3 years ago
class-button.php
557 lines
1 <?php
2 /**
3 * Handles the Button block.
4 *
5 * @package GenerateBlocks
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 /**
13 * Add Button related functions.
14 */
15 class GenerateBlocks_Block_Button {
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 return [
35 'backgroundColor' => '',
36 'backgroundColorHover' => '',
37 'backgroundColorCurrent' => '',
38 'textColor' => '',
39 'textColorHover' => '',
40 'textColorCurrent' => '',
41 'fontFamilyFallback' => '',
42 'googleFont' => false,
43 'googleFontVariants' => '',
44 'icon' => '',
45 'hasIcon' => false,
46 'iconLocation' => 'left',
47 'removeText' => false,
48 'ariaLabel' => '',
49 'gradient' => false,
50 'gradientDirection' => '',
51 'gradientColorOne' => '',
52 'gradientColorOneOpacity' => '',
53 'gradientColorStopOne' => '',
54 'gradientColorTwo' => '',
55 'gradientColorTwoOpacity' => '',
56 'gradientColorStopTwo' => '',
57 'hasButtonContainer' => false,
58 'variantRole' => '',
59 'buttonType' => 'link',
60 // Deprecated attributes.
61 'backgroundColorOpacity' => 1,
62 'backgroundColorHoverOpacity' => 1,
63 'borderColorHoverOpacity' => 1,
64 'borderColorOpacity' => 1,
65 'fontSize' => false,
66 'fontSizeTablet' => false,
67 'fontSizeMobile' => false,
68 'fontSizeUnit' => 'px',
69 'letterSpacing' => '',
70 'letterSpacingTablet' => '',
71 'letterSpacingMobile' => '',
72 'fontWeight' => '',
73 'textTransform' => '',
74 'alignment' => '',
75 'alignmentTablet' => '',
76 'alignmentMobile' => '',
77 'fontFamily' => '',
78 'iconPaddingTop' => '',
79 'iconPaddingRight' => '0.5',
80 'iconPaddingBottom' => '',
81 'iconPaddingLeft' => '',
82 'iconPaddingTopTablet' => '',
83 'iconPaddingRightTablet' => '',
84 'iconPaddingBottomTablet' => '',
85 'iconPaddingLeftTablet' => '',
86 'iconPaddingTopMobile' => '',
87 'iconPaddingRightMobile' => '',
88 'iconPaddingBottomMobile' => '',
89 'iconPaddingLeftMobile' => '',
90 'iconPaddingUnit' => 'em',
91 'iconSize' => 1,
92 'iconSizeTablet' => '',
93 'iconSizeMobile' => '',
94 'iconSizeUnit' => 'em',
95 'borderColor' => '',
96 'borderColorHover' => '',
97 'borderColorCurrent' => '',
98 ];
99 }
100
101 /**
102 * Store our block ID in memory.
103 *
104 * @param string $id The block ID to store.
105 */
106 public static function store_block_id( $id ) {
107 self::$block_ids[] = $id;
108 }
109
110 /**
111 * Check if our block ID exists.
112 *
113 * @param string $id The block ID to store.
114 */
115 public static function block_id_exists( $id ) {
116 return in_array( $id, (array) self::$block_ids );
117 }
118
119 /**
120 * Compile our CSS data based on our block attributes.
121 *
122 * @param array $attributes Our block attributes.
123 */
124 public static function get_css_data( $attributes ) {
125 $css = new GenerateBlocks_Dynamic_CSS();
126 $desktop_css = new GenerateBlocks_Dynamic_CSS();
127 $tablet_css = new GenerateBlocks_Dynamic_CSS();
128 $tablet_only_css = new GenerateBlocks_Dynamic_CSS();
129 $mobile_css = new GenerateBlocks_Dynamic_CSS();
130 $css_data = [];
131
132 $defaults = generateblocks_get_block_defaults();
133
134 $settings = wp_parse_args(
135 $attributes,
136 $defaults['button']
137 );
138
139 $id = $attributes['uniqueId'];
140 $blockVersion = ! empty( $settings['blockVersion'] ) ? $settings['blockVersion'] : 1;
141
142 // Use legacy settings if needed.
143 if ( $blockVersion < 2 ) {
144 $settings = GenerateBlocks_Legacy_Attributes::get_settings( '1.4.0', 'button', $settings, $attributes );
145 }
146
147 // Map deprecated settings.
148 $settings = GenerateBlocks_Map_Deprecated_Attributes::map_attributes( $settings );
149
150 $selector = generateblocks_get_css_selector( 'button', $attributes );
151 $use_visited_selector = generateblocks_use_visited_selector( 'button', $attributes );
152 $using_global_style = isset( $settings['useGlobalStyle'] ) && $settings['useGlobalStyle'];
153
154 // Back-compatibility for when icon held a value.
155 if ( $settings['icon'] ) {
156 $settings['hasIcon'] = true;
157 }
158
159 $gradientColorStopOneValue = '';
160 $gradientColorStopTwoValue = '';
161
162 if ( $settings['gradient'] ) {
163 if ( $settings['gradientColorOne'] && '' !== $settings['gradientColorStopOne'] ) {
164 $gradientColorStopOneValue = ' ' . $settings['gradientColorStopOne'] . '%';
165 }
166
167 if ( $settings['gradientColorTwo'] && '' !== $settings['gradientColorStopTwo'] ) {
168 $gradientColorStopTwoValue = ' ' . $settings['gradientColorStopTwo'] . '%';
169 }
170 }
171
172 // Only add this CSS once.
173 if ( ! self::$singular_css_added ) {
174 $css->set_selector( '.gb-button' );
175 $css->add_property( 'text-decoration', 'none' );
176
177 $css->set_selector( '.gb-icon svg' );
178 $css->add_property( 'fill', 'currentColor' );
179
180 do_action(
181 'generateblocks_block_one_time_css_data',
182 'button',
183 $settings,
184 $css
185 );
186
187 self::$singular_css_added = true;
188 }
189
190 $visited_selector = $use_visited_selector
191 ? ', ' . $selector . ':visited'
192 : '';
193
194 $css->set_selector( $selector . $visited_selector );
195 generateblocks_add_layout_css( $css, $settings );
196 generateblocks_add_sizing_css( $css, $settings );
197 generateblocks_add_flex_child_css( $css, $settings );
198 generateblocks_add_typography_css( $css, $settings );
199 generateblocks_add_spacing_css( $css, $settings );
200 generateblocks_add_border_css( $css, $settings );
201 $css->add_property( 'background-color', generateblocks_hex2rgba( $settings['backgroundColor'], $settings['backgroundColorOpacity'] ) );
202 $css->add_property( 'color', $settings['textColor'] );
203
204 if ( $settings['gradient'] ) {
205 $css->add_property( 'background-image', 'linear-gradient(' . $settings['gradientDirection'] . 'deg, ' . generateblocks_hex2rgba( $settings['gradientColorOne'], $settings['gradientColorOneOpacity'] ) . $gradientColorStopOneValue . ', ' . generateblocks_hex2rgba( $settings['gradientColorTwo'], $settings['gradientColorTwoOpacity'] ) . $gradientColorStopTwoValue . ')' );
206 }
207
208 if ( $blockVersion < 3 && ! $using_global_style ) {
209 $css->add_property( 'display', 'inline-flex' );
210 $css->add_property( 'align-items', 'center' );
211 $css->add_property( 'justify-content', 'center' );
212 $css->add_property( 'text-align', 'center' );
213 }
214
215 $css->set_selector( $selector . ':hover, ' . $selector . ':active, ' . $selector . ':focus' );
216 generateblocks_add_border_color_css( $css, $settings, 'Hover' );
217 $css->add_property( 'background-color', generateblocks_hex2rgba( $settings['backgroundColorHover'], $settings['backgroundColorHoverOpacity'] ) );
218 $css->add_property( 'color', $settings['textColorHover'] );
219
220 $visited_selector = $use_visited_selector
221 ? ', ' . $selector . '.gb-block-is-current:visited'
222 : '';
223
224 $current_selector = sprintf(
225 '%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',
226 $selector
227 );
228
229 $css->set_selector( $current_selector . $visited_selector );
230 generateblocks_add_border_color_css( $css, $settings, 'Current' );
231 $css->add_property( 'background-color', $settings['backgroundColorCurrent'] );
232 $css->add_property( 'color', $settings['textColorCurrent'] );
233
234 if ( $settings['hasIcon'] ) {
235 $css->set_selector( $selector . ' .gb-icon' );
236
237 if ( $blockVersion < 4 ) {
238 $css->add_property( 'font-size', $settings['iconSize'], $settings['iconSizeUnit'] );
239 }
240
241 $css->add_property( 'line-height', '0' );
242
243 if ( ! $settings['removeText'] ) {
244 if ( $blockVersion < 4 ) {
245 // Need to check for blockVersion here instead of mapping as iconPaddingRight has a default.
246 $css->add_property( 'padding', array( $settings['iconPaddingTop'], $settings['iconPaddingRight'], $settings['iconPaddingBottom'], $settings['iconPaddingLeft'] ), $settings['iconPaddingUnit'] );
247 } else {
248 $css->add_property(
249 'padding',
250 array(
251 generateblocks_get_array_attribute_value( 'paddingTop', $settings['iconStyles'] ),
252 generateblocks_get_array_attribute_value( 'paddingRight', $settings['iconStyles'] ),
253 generateblocks_get_array_attribute_value( 'paddingBottom', $settings['iconStyles'] ),
254 generateblocks_get_array_attribute_value( 'paddingLeft', $settings['iconStyles'] ),
255 )
256 );
257 }
258 }
259
260 if ( $blockVersion < 3 ) {
261 $css->add_property( 'align-items', 'center' );
262 $css->add_property( 'display', 'inline-flex' );
263 }
264
265 $css->set_selector( $selector . ' .gb-icon svg' );
266
267 if ( $blockVersion < 4 ) {
268 $css->add_property( 'height', '1em' );
269 $css->add_property( 'width', '1em' );
270 }
271
272 $css->add_property( 'width', generateblocks_get_array_attribute_value( 'width', $settings['iconStyles'] ) );
273 $css->add_property( 'height', generateblocks_get_array_attribute_value( 'height', $settings['iconStyles'] ) );
274 }
275
276 $tablet_css->set_selector( $selector );
277 generateblocks_add_layout_css( $tablet_css, $settings, 'Tablet' );
278 generateblocks_add_sizing_css( $tablet_css, $settings, 'Tablet' );
279 generateblocks_add_flex_child_css( $tablet_css, $settings, 'Tablet' );
280 generateblocks_add_typography_css( $tablet_css, $settings, 'Tablet' );
281 generateblocks_add_spacing_css( $tablet_css, $settings, 'Tablet' );
282 generateblocks_add_border_css( $tablet_css, $settings, 'Tablet' );
283
284 if ( $settings['hasIcon'] ) {
285 $tablet_css->set_selector( $selector . ' .gb-icon' );
286
287 if ( $blockVersion < 4 ) {
288 $tablet_css->add_property( 'font-size', $settings['iconSizeTablet'], $settings['iconSizeUnit'] );
289 }
290
291 if ( ! $settings['removeText'] ) {
292 if ( $blockVersion < 4 ) {
293 $tablet_css->add_property( 'padding', array( $settings['iconPaddingTopTablet'], $settings['iconPaddingRightTablet'], $settings['iconPaddingBottomTablet'], $settings['iconPaddingLeftTablet'] ), $settings['iconPaddingUnit'] );
294 } else {
295 $tablet_css->add_property(
296 'padding',
297 array(
298 generateblocks_get_array_attribute_value( 'paddingTopTablet', $settings['iconStyles'] ),
299 generateblocks_get_array_attribute_value( 'paddingRightTablet', $settings['iconStyles'] ),
300 generateblocks_get_array_attribute_value( 'paddingBottomTablet', $settings['iconStyles'] ),
301 generateblocks_get_array_attribute_value( 'paddingLeftTablet', $settings['iconStyles'] ),
302 )
303 );
304 }
305 }
306
307 $tablet_css->set_selector( $selector . ' .gb-icon svg' );
308 $tablet_css->add_property( 'width', generateblocks_get_array_attribute_value( 'widthTablet', $settings['iconStyles'] ) );
309 $tablet_css->add_property( 'height', generateblocks_get_array_attribute_value( 'heightTablet', $settings['iconStyles'] ) );
310 }
311
312 $mobile_css->set_selector( $selector );
313 generateblocks_add_layout_css( $mobile_css, $settings, 'Mobile' );
314 generateblocks_add_sizing_css( $mobile_css, $settings, 'Mobile' );
315 generateblocks_add_flex_child_css( $mobile_css, $settings, 'Mobile' );
316 generateblocks_add_typography_css( $mobile_css, $settings, 'Mobile' );
317 generateblocks_add_spacing_css( $mobile_css, $settings, 'Mobile' );
318 generateblocks_add_border_css( $mobile_css, $settings, 'Mobile' );
319
320 if ( $settings['hasIcon'] ) {
321 $mobile_css->set_selector( $selector . ' .gb-icon' );
322
323 if ( $blockVersion < 4 ) {
324 $mobile_css->add_property( 'font-size', $settings['iconSizeMobile'], $settings['iconSizeUnit'] );
325 }
326
327 if ( ! $settings['removeText'] ) {
328 if ( $blockVersion < 4 ) {
329 $mobile_css->add_property( 'padding', array( $settings['iconPaddingTopMobile'], $settings['iconPaddingRightMobile'], $settings['iconPaddingBottomMobile'], $settings['iconPaddingLeftMobile'] ), $settings['iconPaddingUnit'] );
330 } else {
331 $mobile_css->add_property(
332 'padding',
333 array(
334 generateblocks_get_array_attribute_value( 'paddingTopMobile', $settings['iconStyles'] ),
335 generateblocks_get_array_attribute_value( 'paddingRightMobile', $settings['iconStyles'] ),
336 generateblocks_get_array_attribute_value( 'paddingBottomMobile', $settings['iconStyles'] ),
337 generateblocks_get_array_attribute_value( 'paddingLeftMobile', $settings['iconStyles'] ),
338 )
339 );
340 }
341 }
342
343 $mobile_css->set_selector( $selector . ' .gb-icon svg' );
344 $mobile_css->add_property( 'width', generateblocks_get_array_attribute_value( 'widthMobile', $settings['iconStyles'] ) );
345 $mobile_css->add_property( 'height', generateblocks_get_array_attribute_value( 'heightMobile', $settings['iconStyles'] ) );
346 }
347
348 // Store this block ID in memory.
349 self::store_block_id( $id );
350
351 /**
352 * Do generateblocks_block_css_data hook
353 *
354 * @since 1.0
355 *
356 * @param string $name The name of our block.
357 * @param array $settings The settings for the current block.
358 * @param object $css Our desktop/main CSS data.
359 * @param object $desktop_css Our desktop only CSS data.
360 * @param object $tablet_css Our tablet CSS data.
361 * @param object $tablet_only_css Our tablet only CSS data.
362 * @param object $mobile_css Our mobile CSS data.
363 */
364 do_action(
365 'generateblocks_block_css_data',
366 'button',
367 $settings,
368 $css,
369 $desktop_css,
370 $tablet_css,
371 $tablet_only_css,
372 $mobile_css
373 );
374
375 return [
376 'main' => $css->css_output(),
377 'desktop' => $desktop_css->css_output(),
378 'tablet' => $tablet_css->css_output(),
379 'tablet_only' => $tablet_only_css->css_output(),
380 'mobile' => $mobile_css->css_output(),
381 ];
382 }
383
384 /**
385 * Wrapper function for our dynamic buttons.
386 *
387 * @since 1.6.0
388 * @param array $attributes The block attributes.
389 * @param string $content The dynamic text to display.
390 * @param WP_Block $block Block instance.
391 */
392 public static function render_block( $attributes, $content, $block ) {
393 if ( ! isset( $attributes['hasUrl'] ) && strpos( trim( $content ), '<a' ) === 0 ) {
394 $attributes['hasUrl'] = true;
395 }
396
397 if ( ! isset( $attributes['useDynamicData'] ) || ! $attributes['useDynamicData'] ) {
398 // Add styles to this block if needed.
399 $content = generateblocks_maybe_add_block_css(
400 $content,
401 [
402 'class_name' => 'GenerateBlocks_Block_Button',
403 'attributes' => $attributes,
404 'block_ids' => self::$block_ids,
405 ]
406 );
407
408 return $content;
409 }
410
411 $allow_empty_content = false;
412
413 // Add an attribute showing we're working with the Button block.
414 $attributes['isButton'] = true;
415
416 if ( empty( $attributes['dynamicContentType'] ) ) {
417 $dynamic_content = GenerateBlocks_Dynamic_Content::get_static_content( $content );
418
419 if ( ! empty( $attributes['hasIcon'] ) && ! empty( $attributes['removeText'] ) ) {
420 // Allow icon-only items to continue.
421 $allow_empty_content = true;
422 }
423 } else {
424 $dynamic_content = GenerateBlocks_Dynamic_Content::get_content( $attributes, $block );
425 }
426
427 if ( ! $dynamic_content && '0' !== $dynamic_content && ! $allow_empty_content ) {
428 return '';
429 }
430
431 $defaults = generateblocks_get_block_defaults();
432
433 $settings = wp_parse_args(
434 $attributes,
435 $defaults['button']
436 );
437
438 $classNames = array(
439 'gb-button',
440 'gb-button-' . $settings['uniqueId'],
441 );
442
443 if ( ! empty( $settings['className'] ) ) {
444 $classNames[] = $settings['className'];
445 }
446
447 if ( empty( $settings['hasIcon'] ) ) {
448 $classNames[] = 'gb-button-text';
449 }
450
451 $relAttributes = array();
452
453 if ( ! empty( $settings['relNoFollow'] ) ) {
454 $relAttributes[] = 'nofollow';
455 }
456
457 if ( ! empty( $settings['target'] ) ) {
458 $relAttributes[] = 'noopener';
459 $relAttributes[] = 'noreferrer';
460 }
461
462 if ( ! empty( $settings['relSponsored'] ) ) {
463 $relAttributes[] = 'sponsored';
464 }
465
466 $icon_html = '';
467
468 // Extract our icon from the static HTML.
469 if ( $settings['hasIcon'] ) {
470 $icon_html = GenerateBlocks_Dynamic_Content::get_icon_html( $content );
471 }
472
473 // Add styles to this block if needed.
474 $output = generateblocks_maybe_add_block_css(
475 '',
476 [
477 'class_name' => 'GenerateBlocks_Block_Button',
478 'attributes' => $attributes,
479 'block_ids' => self::$block_ids,
480 ]
481 );
482
483 foreach ( (array) $dynamic_content as $content ) {
484 $tagName = 'span';
485
486 $dynamic_link = GenerateBlocks_Dynamic_Content::get_dynamic_url( $attributes, $block );
487
488 if ( ! empty( $content['attributes']['href'] ) || $dynamic_link ) {
489 $tagName = 'a';
490 }
491
492 if ( 'button' === $settings['buttonType'] ) {
493 $tagName = 'button';
494 }
495
496 $button_attributes = array(
497 'id' => ! empty( $settings['anchor'] ) ? $settings['anchor'] : null,
498 'class' => implode( ' ', $classNames ),
499 'href' => 'a' === $tagName ? $dynamic_link : null,
500 'rel' => ! empty( $relAttributes ) ? implode( ' ', $relAttributes ) : null,
501 'target' => ! empty( $settings['target'] ) ? '_blank' : null,
502 'aria-label' => ! empty( $settings['ariaLabel'] ) ? $settings['ariaLabel'] : null,
503 );
504
505 if ( isset( $content['attributes'] ) ) {
506 foreach ( $content['attributes'] as $attribute => $value ) {
507 if ( 'class' === $attribute ) {
508 $button_attributes[ $attribute ] .= ' ' . $value;
509 } else {
510 $button_attributes[ $attribute ] = $value;
511 }
512 }
513 }
514
515 $output .= sprintf(
516 '<%1$s %2$s>',
517 $tagName,
518 generateblocks_attr(
519 'dynamic-button',
520 $button_attributes,
521 $settings,
522 $block
523 )
524 );
525
526 if ( $icon_html ) {
527 if ( 'left' === $settings['iconLocation'] ) {
528 $output .= $icon_html;
529 }
530
531 $output .= '<span class="gb-button-text">';
532 }
533
534 if ( isset( $content['content'] ) ) {
535 $output .= $content['content'];
536 } else {
537 $output .= $content;
538 }
539
540 if ( $icon_html ) {
541 $output .= '</span>';
542
543 if ( 'right' === $settings['iconLocation'] ) {
544 $output .= $icon_html;
545 }
546 }
547
548 $output .= sprintf(
549 '</%s>',
550 $tagName
551 );
552 }
553
554 return $output;
555 }
556 }
557