PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 1.6.4
Kubio AI Page Builder v1.6.4
2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / lib / src / Core / Element.php
kubio / lib / src / Core Last commit date
Background 3 years ago Blocks 3 years ago GlobalElements 4 years ago Layout 4 years ago License 4 years ago Separators 4 years ago StyleManager 3 years ago Styles 4 years ago Activation.php 3 years ago Backup.php 4 years ago CustomizerImporter.php 3 years ago Deactivation.php 4 years ago EditInKubioCustomizerPanel.php 4 years ago Element.php 4 years ago ElementBase.php 4 years ago Importer.php 3 years ago InnerBlocks.php 4 years ago LodashBasic.php 4 years ago Registry.php 4 years ago Utils.php 3 years ago
Element.php
367 lines
1 <?php
2
3 namespace Kubio\Core;
4
5 use function array_shift;
6 use function explode;
7 use function is_array;
8 use function is_string;
9 use function strpos;
10
11 class Element extends ElementBase {
12
13 const DIV = 'div';
14 const SPAN = 'span';
15 const IMAGE = 'img';
16 const A = 'a';
17 const FRAGMENT = '<>';
18 const ALLOWED_ATTRIBUTES = array(
19 'hidden',
20 'high',
21 'href',
22 'hreflang',
23 'http-equiv',
24 'icon',
25 'id',
26 'ismap',
27 'itemprop',
28 'keytype',
29 'kind',
30 'label',
31 'lang',
32 'language',
33 'list',
34 'loop',
35 'low',
36 'manifest',
37 'max',
38 'maxlength',
39 'media',
40 'method',
41 'min',
42 'multiple',
43 'name',
44 'novalidate',
45 'open',
46 'optimum',
47 'pattern',
48 'ping',
49 'placeholder',
50 'poster',
51 'preload',
52 'pubdate',
53 'radiogroup',
54 'readonly',
55 'rel',
56 'required',
57 'reversed',
58 'rows',
59 'rowspan',
60 'sandbox',
61 'spellcheck',
62 'scope',
63 'scoped',
64 'seamless',
65 'selected',
66 'shape',
67 'size',
68 'sizes',
69 'span',
70 'src',
71 'srcdoc',
72 'srclang',
73 'srcset',
74 'start',
75 'step',
76 'style',
77 'summary',
78 'tabindex',
79 'target',
80 'title',
81 'type',
82 'usemap',
83 'value',
84 'width',
85 'wrap',
86 'border',
87 'buffered',
88 'challenge',
89 'charset',
90 'checked',
91 'cite',
92 'class',
93 'code',
94 'codebase',
95 'color',
96 'cols',
97 'colspan',
98 'content',
99 'contenteditable',
100 'contextmenu',
101 'controls',
102 'coords',
103 'data',
104 'datetime',
105 'default',
106 'defer',
107 'dir',
108 'dirname',
109 'disabled',
110 'download',
111 'draggable',
112 'dropzone',
113 'enctype',
114 'for',
115 'form',
116 'formaction',
117 'headers',
118 'height',
119 'accept',
120 'accept-charset',
121 'accesskey',
122 'action',
123 'align',
124 'alt',
125 'async',
126 'autocomplete',
127 'autofocus',
128 'autoplay',
129 'autosave',
130 'bgcolor',
131 );
132
133 const SELF_CLOSING_TAGS = array(
134 'area',
135 'base',
136 'br',
137 'embed',
138 'hr',
139 // "iframe", - self closing iframe break chrome
140 'img',
141 'input',
142 'link',
143 'meta',
144 'param',
145 'source',
146 'track',
147
148 );
149
150 public static $allowedAttributesByName = true;
151 public $block;
152 protected $type;
153 protected $props;
154 protected $filters = null;
155 protected $children = array();
156 protected $innerHTML = '';
157 protected $shouldRender = true;
158
159
160 function __construct( $type, $props = array(), $children = array(), $block = null ) {
161 self::$allowedAttributesByName = array_fill_keys( self::ALLOWED_ATTRIBUTES, true );
162
163 $this->type = $type;
164
165 $this->children = $children;
166 $this->block = $block;
167
168 $this->resolveComputed( $props );
169
170 if ( isset( $props['innerHTML'] ) ) {
171 $this->innerHTML = $props['innerHTML'];
172 unset( $props['innerHTML'] );
173 }
174
175 if ( isset( $props['shouldRender'] ) ) {
176 $this->shouldRender = $props['shouldRender'];
177 unset( $props['shouldRender'] );
178 }
179
180 if ( ! empty( $props['filters'] ) ) {
181 $this->filters = $props['filters'];
182 unset( $props['filters'] );
183 }
184
185 if ( isset( $props['disableStyleClasses'] ) ) {
186 $this->disableStyleClasses = $props['disableStyleClasses'];
187 unset( $props['disableStyleClasses'] );
188 }
189
190 $this->props = $props;
191 }
192
193 function resolveComputed( &$props ) {
194 foreach ( $props as $name => $value ) {
195 if ( is_string( $value ) ) {
196 if ( strpos( $value, 'computed.' ) === 0 ) {
197 $props[ $name ] = $this->getComputed( $value );
198 }
199 }
200
201 if ( is_array( $value ) ) {
202 $this->resolveComputed( $value );
203 }
204 }
205 }
206
207 function getComputed( $path, $defaultValue = null ) {
208 $paths = explode( '.', $path );
209 array_shift( $paths );
210
211 return LodashBasic::get( $this->block->computed(), $paths, $defaultValue );
212 }
213
214 function getClassName() {
215 return $this->getProp( 'className', array() );
216 }
217
218 function getProp( $name, $default = null ) {
219 return LodashBasic::get( $this->props, $name, $default );
220 }
221
222 function extendProps( $extend ) {
223 $this->props = LodashBasic::merge( $extend, $this->props );
224 }
225
226 function setChildren( $children ) {
227 $this->children = $children;
228 }
229
230 function mergeProps( ...$arrays ) {
231 $result = array();
232 foreach ( $arrays as $props ) {
233 if ( $props ) {
234 foreach ( $props as $prop_name => $prop_value ) {
235 $result_value = LodashBasic::get( $result, $prop_name, array() );
236 if ( isset( $prop_value ) ) {
237 switch ( $prop_name ) {
238 case 'className':
239 $result[ $prop_name ] = LodashBasic::concat( $result_value, $prop_value );
240 break;
241 case 'style':
242 $result[ $prop_name ] = LodashBasic::merge( $result_value, $prop_value );
243 break;
244 default:
245 $result[ $prop_name ] = $prop_value;
246 }
247 }
248 }
249 }
250 }
251 $result['className'] = LodashBasic::identity( LodashBasic::uniq( $result['className'] ) );
252
253 return $result;
254 }
255
256 function __toString() {
257 if ( ! $this->shouldRender ) {
258 return '';
259 }
260
261 $output = '';
262 $tags = array();
263
264 if ( $this->type !== self::FRAGMENT && in_array( $this->tagName(), self::SELF_CLOSING_TAGS ) ) {
265 $output = "<{$this->tagName()} {$this->getAttributesAsString()} />";
266 } else {
267 if ( $this->type !== self::FRAGMENT ) {
268 $tags[] = "<{$this->tagName()} {$this->getAttributesAsString()}>";
269 }
270
271 // check for non empty strings that return false on validation like. ex: '0'
272 $non_empty_string = is_string( $this->innerHTML ) && strlen( $this->innerHTML );
273 if ( $this->innerHTML || $non_empty_string ) {
274 $tags[] = $this->innerHTML;
275 } else {
276 foreach ( $this->children as $child ) {
277 if ( $child ) {
278 $tags[] = $child;
279 }
280 }
281 }
282
283 if ( $this->type !== self::FRAGMENT ) {
284 $tags[] = "</{$this->tagName()}>";
285 }
286
287 $output = implode( '', $tags );
288 }
289
290 if ( ! empty( $this->filters ) ) {
291 foreach ( $this->filters as $filter ) {
292 $output = apply_filters( $filter, $output );
293 }
294 }
295
296 return $output;
297 }
298
299 function tagName() {
300 return $this->type;
301 }
302
303 function getAttributesAsString() {
304 $attrs = array();
305 $props = $this->getProps();
306
307 foreach ( $props as $prop_name => $prop_value ) {
308 $attr_name = $prop_name;
309 $attr_value = $prop_value;
310 switch ( $prop_name ) {
311 case 'className':
312 $attr_name = 'class';
313 $attr_value = $this->classAttribute( $prop_value );
314 break;
315 case 'style':
316 $attr_value = $this->styleAttribute( $prop_value );
317 break;
318 }
319 if ( is_string( $attr_value ) ) {
320 if ( strpos( $attr_name, 'data-' ) === 0 || isset( self::$allowedAttributesByName[ $attr_name ] ) ) {
321 $attrs[] = $attr_name . '="' . esc_attr( $attr_value ) . '"';
322 }
323 }
324 }
325
326 return implode( ' ', $attrs );
327 }
328
329 function getProps() {
330 return $this->props;
331 }
332
333 function setProps( $props ) {
334 $this->props = $props;
335 }
336
337 function classAttribute( $classes ) {
338 $cls = array();
339 if ( is_string( $classes ) ) {
340 return $classes;
341 }
342 if ( is_array( $classes ) ) {
343 foreach ( $classes as $class_name => $class_value ) {
344 if ( ! is_numeric( $class_name ) ) {
345 if ( ! ! $class_value ) {
346 $cls[] = $class_name;
347 }
348 } else {
349 $cls[] = $class_value;
350 }
351 }
352 }
353
354 return implode( ' ', $cls );
355 }
356
357 function styleAttribute( $style ) {
358 $styles = array();
359 foreach ( $style as $s_name => $s_value ) {
360 $styles[] = LodashBasic::kebabCase( $s_name ) . ':' . $s_value;
361 }
362
363 return implode( ';', $styles );
364 }
365 }
366
367