PluginProbe
bBlocks – Essential Gutenberg Blocks & Patterns Collection / 2.1.8
bBlocks – Essential Gutenberg Blocks & Patterns Collection v2.1.8
2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.43 2.0.42 2.0.41 2.0.40 2.0.39 2.0.38 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.5.1 1.5.2 1.5.3 All 108 releases
b-blocks / build / timeline-item / render.php

render.php in bBlocks – Essential Gutenberg Blocks & Patterns Collection 2.1.8, at build/timeline-item/render.php

127 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 $id = wp_unique_id( 'bBlocksTimelineItem-' );
7 $attributes = BBlocks\Inc\Sanitize::attributes( $attributes );
8
9 $item = isset( $attributes['item'] ) && is_array( $attributes['item'] ) ? $attributes['item'] : array();
10
11 $side = isset( $item['side'] ) ? sanitize_key( (string) $item['side'] ) : '';
12 $side = in_array( $side, array( 'left', 'right' ), true ) ? $side : '';
13
14 // Empty means follow the parent Timeline, so only an explicit choice emits a
15 // class. Mirrors getTimelineItemClasses in the parent's utils/functions.js.
16 $arrowAlign = isset( $item['arrowAlign'] ) ? sanitize_key( (string) $item['arrowAlign'] ) : '';
17 $arrowAlign = in_array( $arrowAlign, array( 'start', 'center', 'end' ), true ) ? $arrowAlign : '';
18
19 // The date is a RichText field, so it can carry inline formatting — bold,
20 // links, colour. wp_kses_post keeps exactly what a post is allowed to hold
21 // and strips the rest, matching how every other RichText in the plugin is
22 // rendered.
23 $date = isset( $attributes['date'] ) ? wp_kses_post( (string) $attributes['date'] ) : '';
24
25 /**
26 * The marker icon is an inline SVG from the bpl-tools icon library rather
27 * than a font class, so it carries no webfont dependency — but it also means
28 * raw markup reaches the page and has to be filtered.
29 *
30 * The allowlist below is not guesswork: it is every element and attribute
31 * that actually occurs across all 4,354 icons in the three bundled libraries
32 * (Font Awesome, Bootstrap, Lucide). Anything outside it — script, style, on*
33 * handlers, foreignObject — is stripped by wp_kses.
34 */
35 $svgAttr = array(
36 'xmlns' => true,
37 'viewbox' => true,
38 'width' => true,
39 'height' => true,
40 'fill' => true,
41 'fill-rule' => true,
42 'fill-opacity' => true,
43 'stroke' => true,
44 'stroke-width' => true,
45 'stroke-linecap' => true,
46 'stroke-linejoin' => true,
47 'class' => true,
48 'id' => true,
49 'transform' => true,
50 'aria-hidden' => true,
51 'focusable' => true,
52 );
53
54 $shapeAttr = array(
55 'd' => true,
56 'points' => true,
57 'cx' => true,
58 'cy' => true,
59 'r' => true,
60 'rx' => true,
61 'ry' => true,
62 'x' => true,
63 'y' => true,
64 'x1' => true,
65 'y1' => true,
66 'x2' => true,
67 'y2' => true,
68 'width' => true,
69 'height' => true,
70 'fill' => true,
71 'fill-rule' => true,
72 'fill-opacity' => true,
73 'stroke' => true,
74 'stroke-width' => true,
75 'stroke-linecap' => true,
76 'stroke-linejoin' => true,
77 'transform' => true,
78 );
79
80 $iconAllowed = array(
81 'svg' => $svgAttr,
82 'g' => $shapeAttr,
83 'path' => $shapeAttr,
84 'circle' => $shapeAttr,
85 'ellipse' => $shapeAttr,
86 'rect' => $shapeAttr,
87 'line' => $shapeAttr,
88 'polyline' => $shapeAttr,
89 'polygon' => $shapeAttr,
90 );
91
92 $icon = isset( $attributes['icon'] ) ? wp_kses( (string) $attributes['icon'], $iconAllowed ) : '';
93
94 $itemClasses = trim(
95 'b-blocks-timeline-item'
96 . ( $side ? ' b-blocks-timeline-side-' . $side : '' )
97 . ( $arrowAlign ? ' b-blocks-timeline-item-arrow-' . $arrowAlign : '' )
98 );
99 ?>
100 <div
101 <?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- get_block_wrapper_attributes() is properly escaped ?>
102 <?php echo get_block_wrapper_attributes( array( 'class' => $itemClasses ) ); ?>
103 id='<?php echo esc_attr( $id ); ?>'
104 data-attributes='<?php echo esc_attr( wp_json_encode( $attributes ) ); ?>'
105 >
106 <div class='b-blocks-timeline-item-style'></div>
107
108 <div class='b-blocks-timeline-content'>
109 <div class='b-blocks-timeline-card'>
110 <?php
111 // $content is this entry's inner blocks, each of which rendered
112 // and escaped its own markup.
113 echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- inner blocks render their own escaped markup
114 ?>
115 </div>
116 </div>
117
118 <div class='b-blocks-timeline-marker' aria-hidden='true'>
119 <?php
120 // Sanitized with wp_kses against the icon allowlist above.
121 echo $icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- filtered by wp_kses above
122 ?>
123 </div>
124
125 <div class='b-blocks-timeline-date'><?php echo $date; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sanitized with wp_kses_post above ?></div>
126 </div>
127