PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.2.1
GenerateBlocks v2.2.1
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-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 2 years 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-button.php
554 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 // Singular CSS is no longer supported since 1.9.0.
175 do_action(
176 'generateblocks_block_one_time_css_data',
177 'button',
178 $settings,
179 $css
180 );
181
182 self::$singular_css_added = true;
183 }
184
185 $visited_selector = $use_visited_selector
186 ? ', ' . $selector . ':visited'
187 : '';
188
189 $css->set_selector( $selector . $visited_selector );
190 generateblocks_add_layout_css( $css, $settings );
191 generateblocks_add_sizing_css( $css, $settings );
192 generateblocks_add_flex_child_css( $css, $settings );
193 generateblocks_add_typography_css( $css, $settings );
194 generateblocks_add_spacing_css( $css, $settings );
195 generateblocks_add_border_css( $css, $settings );
196 $css->add_property( 'background-color', generateblocks_hex2rgba( $settings['backgroundColor'], $settings['backgroundColorOpacity'] ) );
197 $css->add_property( 'color', $settings['textColor'] );
198 $css->add_property( 'text-decoration', 'none' );
199
200 if ( $settings['gradient'] ) {
201 $css->add_property( 'background-image', 'linear-gradient(' . $settings['gradientDirection'] . 'deg, ' . generateblocks_hex2rgba( $settings['gradientColorOne'], $settings['gradientColorOneOpacity'] ) . $gradientColorStopOneValue . ', ' . generateblocks_hex2rgba( $settings['gradientColorTwo'], $settings['gradientColorTwoOpacity'] ) . $gradientColorStopTwoValue . ')' );
202 }
203
204 if ( $blockVersion < 3 && ! $using_global_style ) {
205 $css->add_property( 'display', 'inline-flex' );
206 $css->add_property( 'align-items', 'center' );
207 $css->add_property( 'justify-content', 'center' );
208 $css->add_property( 'text-align', 'center' );
209 }
210
211 $css->set_selector( $selector . ':hover, ' . $selector . ':active, ' . $selector . ':focus' );
212 generateblocks_add_border_color_css( $css, $settings, 'Hover' );
213 $css->add_property( 'background-color', generateblocks_hex2rgba( $settings['backgroundColorHover'], $settings['backgroundColorHoverOpacity'] ) );
214 $css->add_property( 'color', $settings['textColorHover'] );
215
216 $visited_selector = $use_visited_selector
217 ? ', ' . $selector . '.gb-block-is-current:visited'
218 : '';
219
220 $current_selector = sprintf(
221 '%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',
222 $selector
223 );
224
225 $css->set_selector( $current_selector . $visited_selector );
226 generateblocks_add_border_color_css( $css, $settings, 'Current' );
227 $css->add_property( 'background-color', $settings['backgroundColorCurrent'] );
228 $css->add_property( 'color', $settings['textColorCurrent'] );
229
230 if ( $settings['hasIcon'] ) {
231 $css->set_selector( $selector . ' .gb-icon' );
232
233 if ( $blockVersion < 4 ) {
234 $css->add_property( 'font-size', $settings['iconSize'], $settings['iconSizeUnit'] );
235 }
236
237 $css->add_property( 'line-height', '0' );
238
239 if ( ! $settings['removeText'] ) {
240 if ( $blockVersion < 4 ) {
241 // Need to check for blockVersion here instead of mapping as iconPaddingRight has a default.
242 $css->add_property( 'padding', array( $settings['iconPaddingTop'], $settings['iconPaddingRight'], $settings['iconPaddingBottom'], $settings['iconPaddingLeft'] ), $settings['iconPaddingUnit'] );
243 } else {
244 $css->add_property(
245 'padding',
246 array(
247 generateblocks_get_array_attribute_value( 'paddingTop', $settings['iconStyles'] ),
248 generateblocks_get_array_attribute_value( 'paddingRight', $settings['iconStyles'] ),
249 generateblocks_get_array_attribute_value( 'paddingBottom', $settings['iconStyles'] ),
250 generateblocks_get_array_attribute_value( 'paddingLeft', $settings['iconStyles'] ),
251 )
252 );
253 }
254 }
255
256 if ( $blockVersion < 3 ) {
257 $css->add_property( 'align-items', 'center' );
258 $css->add_property( 'display', 'inline-flex' );
259 }
260
261 $css->set_selector( $selector . ' .gb-icon svg' );
262
263 if ( $blockVersion < 4 ) {
264 $css->add_property( 'height', '1em' );
265 $css->add_property( 'width', '1em' );
266 }
267
268 $css->add_property( 'width', generateblocks_get_array_attribute_value( 'width', $settings['iconStyles'] ) );
269 $css->add_property( 'height', generateblocks_get_array_attribute_value( 'height', $settings['iconStyles'] ) );
270 $css->add_property( 'fill', 'currentColor' );
271 }
272
273 $tablet_css->set_selector( $selector );
274 generateblocks_add_layout_css( $tablet_css, $settings, 'Tablet' );
275 generateblocks_add_sizing_css( $tablet_css, $settings, 'Tablet' );
276 generateblocks_add_flex_child_css( $tablet_css, $settings, 'Tablet' );
277 generateblocks_add_typography_css( $tablet_css, $settings, 'Tablet' );
278 generateblocks_add_spacing_css( $tablet_css, $settings, 'Tablet' );
279 generateblocks_add_border_css( $tablet_css, $settings, 'Tablet' );
280
281 if ( $settings['hasIcon'] ) {
282 $tablet_css->set_selector( $selector . ' .gb-icon' );
283
284 if ( $blockVersion < 4 ) {
285 $tablet_css->add_property( 'font-size', $settings['iconSizeTablet'], $settings['iconSizeUnit'] );
286 }
287
288 if ( ! $settings['removeText'] ) {
289 if ( $blockVersion < 4 ) {
290 $tablet_css->add_property( 'padding', array( $settings['iconPaddingTopTablet'], $settings['iconPaddingRightTablet'], $settings['iconPaddingBottomTablet'], $settings['iconPaddingLeftTablet'] ), $settings['iconPaddingUnit'] );
291 } else {
292 $tablet_css->add_property(
293 'padding',
294 array(
295 generateblocks_get_array_attribute_value( 'paddingTopTablet', $settings['iconStyles'] ),
296 generateblocks_get_array_attribute_value( 'paddingRightTablet', $settings['iconStyles'] ),
297 generateblocks_get_array_attribute_value( 'paddingBottomTablet', $settings['iconStyles'] ),
298 generateblocks_get_array_attribute_value( 'paddingLeftTablet', $settings['iconStyles'] ),
299 )
300 );
301 }
302 }
303
304 $tablet_css->set_selector( $selector . ' .gb-icon svg' );
305 $tablet_css->add_property( 'width', generateblocks_get_array_attribute_value( 'widthTablet', $settings['iconStyles'] ) );
306 $tablet_css->add_property( 'height', generateblocks_get_array_attribute_value( 'heightTablet', $settings['iconStyles'] ) );
307 }
308
309 $mobile_css->set_selector( $selector );
310 generateblocks_add_layout_css( $mobile_css, $settings, 'Mobile' );
311 generateblocks_add_sizing_css( $mobile_css, $settings, 'Mobile' );
312 generateblocks_add_flex_child_css( $mobile_css, $settings, 'Mobile' );
313 generateblocks_add_typography_css( $mobile_css, $settings, 'Mobile' );
314 generateblocks_add_spacing_css( $mobile_css, $settings, 'Mobile' );
315 generateblocks_add_border_css( $mobile_css, $settings, 'Mobile' );
316
317 if ( $settings['hasIcon'] ) {
318 $mobile_css->set_selector( $selector . ' .gb-icon' );
319
320 if ( $blockVersion < 4 ) {
321 $mobile_css->add_property( 'font-size', $settings['iconSizeMobile'], $settings['iconSizeUnit'] );
322 }
323
324 if ( ! $settings['removeText'] ) {
325 if ( $blockVersion < 4 ) {
326 $mobile_css->add_property( 'padding', array( $settings['iconPaddingTopMobile'], $settings['iconPaddingRightMobile'], $settings['iconPaddingBottomMobile'], $settings['iconPaddingLeftMobile'] ), $settings['iconPaddingUnit'] );
327 } else {
328 $mobile_css->add_property(
329 'padding',
330 array(
331 generateblocks_get_array_attribute_value( 'paddingTopMobile', $settings['iconStyles'] ),
332 generateblocks_get_array_attribute_value( 'paddingRightMobile', $settings['iconStyles'] ),
333 generateblocks_get_array_attribute_value( 'paddingBottomMobile', $settings['iconStyles'] ),
334 generateblocks_get_array_attribute_value( 'paddingLeftMobile', $settings['iconStyles'] ),
335 )
336 );
337 }
338 }
339
340 $mobile_css->set_selector( $selector . ' .gb-icon svg' );
341 $mobile_css->add_property( 'width', generateblocks_get_array_attribute_value( 'widthMobile', $settings['iconStyles'] ) );
342 $mobile_css->add_property( 'height', generateblocks_get_array_attribute_value( 'heightMobile', $settings['iconStyles'] ) );
343 }
344
345 // Store this block ID in memory.
346 self::store_block_id( $id );
347
348 /**
349 * Do generateblocks_block_css_data hook
350 *
351 * @since 1.0
352 *
353 * @param string $name The name of our block.
354 * @param array $settings The settings for the current block.
355 * @param object $css Our desktop/main CSS data.
356 * @param object $desktop_css Our desktop only CSS data.
357 * @param object $tablet_css Our tablet CSS data.
358 * @param object $tablet_only_css Our tablet only CSS data.
359 * @param object $mobile_css Our mobile CSS data.
360 */
361 do_action(
362 'generateblocks_block_css_data',
363 'button',
364 $settings,
365 $css,
366 $desktop_css,
367 $tablet_css,
368 $tablet_only_css,
369 $mobile_css
370 );
371
372 return [
373 'main' => $css->css_output(),
374 'desktop' => $desktop_css->css_output(),
375 'tablet' => $tablet_css->css_output(),
376 'tablet_only' => $tablet_only_css->css_output(),
377 'mobile' => $mobile_css->css_output(),
378 ];
379 }
380
381 /**
382 * Wrapper function for our dynamic buttons.
383 *
384 * @since 1.6.0
385 * @param array $attributes The block attributes.
386 * @param string $content The dynamic text to display.
387 * @param WP_Block $block Block instance.
388 */
389 public static function render_block( $attributes, $content, $block ) {
390 if ( ! isset( $attributes['hasUrl'] ) && strpos( trim( $content ), '<a' ) === 0 ) {
391 $attributes['hasUrl'] = true;
392 }
393
394 if ( ! isset( $attributes['useDynamicData'] ) || ! $attributes['useDynamicData'] ) {
395 // Add styles to this block if needed.
396 $content = generateblocks_maybe_add_block_css(
397 $content,
398 [
399 'class_name' => 'GenerateBlocks_Block_Button',
400 'attributes' => $attributes,
401 'block_ids' => self::$block_ids,
402 ]
403 );
404
405 return $content;
406 }
407
408 $allow_empty_content = false;
409
410 // Add an attribute showing we're working with the Button block.
411 $attributes['isButton'] = true;
412
413 if ( empty( $attributes['dynamicContentType'] ) ) {
414 $dynamic_content = GenerateBlocks_Dynamic_Content::get_static_content( $content );
415
416 if ( ! empty( $attributes['hasIcon'] ) && ! empty( $attributes['removeText'] ) ) {
417 // Allow icon-only items to continue.
418 $allow_empty_content = true;
419 }
420 } else {
421 $dynamic_content = GenerateBlocks_Dynamic_Content::get_content( $attributes, $block );
422 }
423
424 if ( ! $dynamic_content && '0' !== $dynamic_content && ! $allow_empty_content ) {
425 return '';
426 }
427
428 $defaults = generateblocks_get_block_defaults();
429
430 $settings = wp_parse_args(
431 $attributes,
432 $defaults['button']
433 );
434
435 $classNames = array(
436 'gb-button',
437 'gb-button-' . $settings['uniqueId'],
438 );
439
440 if ( ! empty( $settings['className'] ) ) {
441 $classNames[] = $settings['className'];
442 }
443
444 if ( empty( $settings['hasIcon'] ) ) {
445 $classNames[] = 'gb-button-text';
446 }
447
448 $relAttributes = array();
449
450 if ( ! empty( $settings['relNoFollow'] ) ) {
451 $relAttributes[] = 'nofollow';
452 }
453
454 if ( ! empty( $settings['target'] ) ) {
455 $relAttributes[] = 'noopener';
456 $relAttributes[] = 'noreferrer';
457 }
458
459 if ( ! empty( $settings['relSponsored'] ) ) {
460 $relAttributes[] = 'sponsored';
461 }
462
463 $icon_html = '';
464
465 // Extract our icon from the static HTML.
466 if ( $settings['hasIcon'] ) {
467 $icon_html = GenerateBlocks_Dynamic_Content::get_icon_html( $content );
468 }
469
470 // Add styles to this block if needed.
471 $output = generateblocks_maybe_add_block_css(
472 '',
473 [
474 'class_name' => 'GenerateBlocks_Block_Button',
475 'attributes' => $attributes,
476 'block_ids' => self::$block_ids,
477 ]
478 );
479
480 foreach ( (array) $dynamic_content as $content ) {
481 $tagName = 'span';
482
483 $dynamic_link = GenerateBlocks_Dynamic_Content::get_dynamic_url( $attributes, $block );
484
485 if ( ! empty( $content['attributes']['href'] ) || $dynamic_link ) {
486 $tagName = 'a';
487 }
488
489 if ( 'button' === $settings['buttonType'] ) {
490 $tagName = 'button';
491 }
492
493 $button_attributes = array(
494 'id' => ! empty( $settings['anchor'] ) ? $settings['anchor'] : null,
495 'class' => implode( ' ', $classNames ),
496 'href' => 'a' === $tagName ? $dynamic_link : null,
497 'rel' => ! empty( $relAttributes ) ? implode( ' ', $relAttributes ) : null,
498 'target' => ! empty( $settings['target'] ) ? '_blank' : null,
499 'aria-label' => ! empty( $settings['ariaLabel'] ) ? $settings['ariaLabel'] : null,
500 );
501
502 if ( isset( $content['attributes'] ) ) {
503 foreach ( $content['attributes'] as $attribute => $value ) {
504 if ( 'class' === $attribute ) {
505 $button_attributes[ $attribute ] .= ' ' . $value;
506 } else {
507 $button_attributes[ $attribute ] = $value;
508 }
509 }
510 }
511
512 $output .= sprintf(
513 '<%1$s %2$s>',
514 $tagName,
515 generateblocks_attr(
516 'dynamic-button',
517 $button_attributes,
518 $settings,
519 $block
520 )
521 );
522
523 if ( $icon_html ) {
524 if ( 'left' === $settings['iconLocation'] ) {
525 $output .= $icon_html;
526 }
527
528 $output .= '<span class="gb-button-text">';
529 }
530
531 if ( isset( $content['content'] ) ) {
532 $output .= $content['content'];
533 } else {
534 $output .= $content;
535 }
536
537 if ( $icon_html ) {
538 $output .= '</span>';
539
540 if ( 'right' === $settings['iconLocation'] ) {
541 $output .= $icon_html;
542 }
543 }
544
545 $output .= sprintf(
546 '</%s>',
547 $tagName
548 );
549 }
550
551 return $output;
552 }
553 }
554