PluginProbe
TableKit – WordPress Table Builder for Data Tables, WooCommerce Product Tables & Post Tables / 2.2.14
TableKit – WordPress Table Builder for Data Tables, WooCommerce Product Tables & Post Tables v2.2.14
2.2.14 2.2.13 2.2.12 2.2.11 2.2.10 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 trunk 1.0.0 1.0.1 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2
← All changes | includes/Helpers/Utils.php +1062 -588 2.2.22.2.14 View file →
@@ -1,5 +1,10 @@
1 1 <?php
2 +/**
3 + * General-purpose helper methods shared across the plugin
4 + *
5 + * @package TableKit
6 + */
2 7
3 8 namespace TableBuilder\Helpers;
4 9
5 10 defined( 'ABSPATH' ) || exit;
@@ -8,9 +13,8 @@
8 13 * Global helper class.
9 14 *
10 15 * @since 1.0.0
11 16 */
12 -
13 17 class Utils {
14 18
15 19 /**
16 20 * Returns an array of allowed HTML tags and attributes for SVG elements.
@@ -17,130 +21,137 @@
17 21 *
18 22 * @return array The array of allowed HTML tags and attributes.
19 23 */
20 24 public static function svg_allowed_html() {
21 - $allowed_svg_tags = [
22 - 'svg' => [
23 - 'xmlns' => true,
24 - 'width' => true,
25 - 'height' => true,
26 - 'viewBox' => true,
27 - 'viewbox' => true,
28 - 'fill' => true,
29 - 'class' => true,
30 - 'aria-hidden' => true,
31 - 'aria-labelledby' => true,
32 - 'role' => true,
25 + $allowed_svg_tags = array(
26 + 'svg' => array(
27 + 'xmlns' => true,
28 + 'width' => true,
29 + 'height' => true,
30 + 'viewBox' => true,
31 + 'viewbox' => true,
32 + 'fill' => true,
33 + 'class' => true,
34 + 'aria-hidden' => true,
35 + 'aria-labelledby' => true,
36 + 'role' => true,
33 37 'preserveaspectratio' => true,
34 - 'version' => true,
35 - ],
36 - 'title' => array( 'title' => true ),
37 - 'g' => [
38 + 'version' => true,
39 + ),
40 + 'title' => array( 'title' => true ),
41 + 'g' => array(
38 42 'transform' => true,
39 - 'style' => true,
40 - 'id' => true,
41 - ],
42 - 'path' => [
43 - 'd' => true,
44 - 'fill' => true,
45 - 'fill-rule' => true,
46 - 'transform' => true,
47 - 'style' => true,
48 - 'opacity' => true,
49 - 'stroke' => true,
50 - 'stroke-width' => true,
43 + 'style' => true,
44 + 'id' => true,
45 + ),
46 + 'path' => array(
47 + 'd' => true,
48 + 'fill' => true,
49 + 'fill-rule' => true,
50 + 'transform' => true,
51 + 'style' => true,
52 + 'opacity' => true,
53 + 'stroke' => true,
54 + 'stroke-width' => true,
51 55 'stroke-miterlimit' => true,
52 - 'stroke-linecap' => true,
53 - 'stroke-linejoin' => true,
54 - 'fill-opacity' => true,
55 - ],
56 - 'circle' => [
57 - 'cx' => true,
58 - 'cy' => true,
59 - 'r' => true,
60 - 'fill' => true,
61 - 'stroke' => true,
56 + 'stroke-linecap' => true,
57 + 'stroke-linejoin' => true,
58 + 'fill-opacity' => true,
59 + ),
60 + 'circle' => array(
61 + 'cx' => true,
62 + 'cy' => true,
63 + 'r' => true,
64 + 'fill' => true,
65 + 'stroke' => true,
62 66 'stroke-width' => true,
63 - ],
64 - 'ellipse' => [
65 - 'cx' => true,
66 - 'cy' => true,
67 - 'rx' => true,
68 - 'ry' => true,
69 - 'fill' => true,
70 - 'stroke' => true,
67 + ),
68 + 'ellipse' => array(
69 + 'cx' => true,
70 + 'cy' => true,
71 + 'rx' => true,
72 + 'ry' => true,
73 + 'fill' => true,
74 + 'stroke' => true,
71 75 'stroke-width' => true,
72 - ],
73 - 'line' => [
74 - 'x1' => true,
75 - 'y1' => true,
76 - 'x2' => true,
77 - 'y2' => true,
78 - 'stroke' => true,
76 + ),
77 + 'line' => array(
78 + 'x1' => true,
79 + 'y1' => true,
80 + 'x2' => true,
81 + 'y2' => true,
82 + 'stroke' => true,
79 83 'stroke-width' => true,
80 - ],
81 - 'polygon' => [
82 - 'points' => true,
83 - 'fill' => true,
84 - 'stroke' => true,
84 + ),
85 + 'polygon' => array(
86 + 'points' => true,
87 + 'fill' => true,
88 + 'stroke' => true,
85 89 'stroke-width' => true,
86 - ],
87 - 'polyline' => [
88 - 'points' => true,
89 - 'fill' => true,
90 - 'stroke' => true,
90 + ),
91 + 'polyline' => array(
92 + 'points' => true,
93 + 'fill' => true,
94 + 'stroke' => true,
91 95 'stroke-width' => true,
92 - ],
93 - 'rect' => [
94 - 'x' => true,
95 - 'y' => true,
96 - 'width' => true,
97 - 'height' => true,
98 - 'fill' => true,
99 - 'stroke' => true,
96 + ),
97 + 'rect' => array(
98 + 'x' => true,
99 + 'y' => true,
100 + 'width' => true,
101 + 'height' => true,
102 + 'fill' => true,
103 + 'stroke' => true,
100 104 'stroke-width' => true,
101 - ],
102 - 'text' => [
103 - 'x' => true,
104 - 'y' => true,
105 - 'dx' => true,
106 - 'dy' => true,
105 + ),
106 + 'text' => array(
107 + 'x' => true,
108 + 'y' => true,
109 + 'dx' => true,
110 + 'dy' => true,
107 111 'text-anchor' => true,
108 - 'style' => true,
109 - ],
110 - 'tspan' => [
111 - 'x' => true,
112 - 'y' => true,
113 - 'dx' => true,
114 - 'dy' => true,
112 + 'style' => true,
113 + ),
114 + 'tspan' => array(
115 + 'x' => true,
116 + 'y' => true,
117 + 'dx' => true,
118 + 'dy' => true,
115 119 'text-anchor' => true,
116 - 'style' => true,
117 - ],
118 - 'defs' => [],
119 - 'lineargradient' => [
120 - 'id' => true,
121 - 'x1' => true,
122 - 'y1' => true,
123 - 'x2' => true,
124 - 'y2' => true,
120 + 'style' => true,
121 + ),
122 + 'defs' => array(),
123 + 'lineargradient' => array(
124 + 'id' => true,
125 + 'x1' => true,
126 + 'y1' => true,
127 + 'x2' => true,
128 + 'y2' => true,
125 129 'gradientunits' => true,
126 - ],
127 - 'stop' => [
128 - 'offset' => true,
129 - 'style' => true,
130 - 'stop-color' => true,
130 + ),
131 + 'stop' => array(
132 + 'offset' => true,
133 + 'style' => true,
134 + 'stop-color' => true,
131 135 'stop-opacity' => true,
132 - ],
133 - 'radialgradient' => [
134 - 'id' => true,
135 - 'cx' => true,
136 - 'cy' => true,
137 - 'r' => true,
138 - 'gradientunits' => true,
136 + ),
137 + 'radialgradient' => array(
138 + 'id' => true,
139 + 'cx' => true,
140 + 'cy' => true,
141 + 'r' => true,
142 + 'gradientunits' => true,
139 143 'gradienttransform' => true,
140 - ],
141 - ];
144 + ),
145 + );
142 146
147 + /**
148 + * Filters the allowed SVG tags and attributes used when sanitizing block output.
149 + *
150 + * @since Unknown
151 + *
152 + * @param array $allowed_svg_tags Allowed SVG elements and their attributes, keyed by tag name.
153 + */
143 154 return apply_filters( 'table_builder_allowed_svg_attrs_tags', $allowed_svg_tags );
144 155 }
145 156
146 157 /**
@@ -152,174 +163,191 @@
152 163 *
153 164 * @return array The array of allowed JSON attribute tags.
154 165 */
155 166 public static function allowed_json_attrs_tags() {
156 - $allowed_json_tags = [
157 - 'object' => [
158 - 'type' => true,
159 - 'properties' => true,
160 - 'required' => true,
167 + $allowed_json_tags = array(
168 + 'object' => array(
169 + 'type' => true,
170 + 'properties' => true,
171 + 'required' => true,
161 172 'additionalProperties' => true,
162 - 'propertyNames' => true,
163 - 'dependencies' => true,
164 - 'minProperties' => true,
165 - 'maxProperties' => true,
166 - ],
167 - 'array' => [
168 - 'type' => true,
169 - 'items' => true,
170 - 'minItems' => true,
171 - 'maxItems' => true,
173 + 'propertyNames' => true,
174 + 'dependencies' => true,
175 + 'minProperties' => true,
176 + 'maxProperties' => true,
177 + ),
178 + 'array' => array(
179 + 'type' => true,
180 + 'items' => true,
181 + 'minItems' => true,
182 + 'maxItems' => true,
172 183 'uniqueItems' => true,
173 - ],
174 - 'string' => [
175 - 'type' => true,
176 - 'minLength' => true,
177 - 'maxLength' => true,
178 - 'pattern' => true,
179 - 'format' => true,
180 - 'contentEncoding' => true,
184 + ),
185 + 'string' => array(
186 + 'type' => true,
187 + 'minLength' => true,
188 + 'maxLength' => true,
189 + 'pattern' => true,
190 + 'format' => true,
191 + 'contentEncoding' => true,
181 192 'contentMediaType' => true,
182 - ],
183 - 'number' => [
184 - 'type' => true,
185 - 'minimum' => true,
186 - 'maximum' => true,
193 + ),
194 + 'number' => array(
195 + 'type' => true,
196 + 'minimum' => true,
197 + 'maximum' => true,
187 198 'exclusiveMinimum' => true,
188 199 'exclusiveMaximum' => true,
189 - 'multipleOf' => true,
190 - ],
191 - 'integer' => [
192 - 'type' => true,
193 - 'minimum' => true,
194 - 'maximum' => true,
200 + 'multipleOf' => true,
201 + ),
202 + 'integer' => array(
203 + 'type' => true,
204 + 'minimum' => true,
205 + 'maximum' => true,
195 206 'exclusiveMinimum' => true,
196 207 'exclusiveMaximum' => true,
197 - ],
198 - 'boolean' => [
208 + ),
209 + 'boolean' => array(
199 210 'type' => true,
200 - ],
201 - 'null' => [
211 + ),
212 + 'null' => array(
202 213 'type' => true,
203 - ],
204 - 'enum' => [
214 + ),
215 + 'enum' => array(
205 216 'type' => true,
206 217 'enum' => true,
207 - ],
208 - 'const' => [
209 - 'type' => true,
218 + ),
219 + 'const' => array(
220 + 'type' => true,
210 221 'const' => true,
211 - ],
212 - 'oneOf' => [
213 - 'type' => true,
222 + ),
223 + 'oneOf' => array(
224 + 'type' => true,
214 225 'oneOf' => true,
215 - ],
216 - 'allOf' => [
217 - 'type' => true,
226 + ),
227 + 'allOf' => array(
228 + 'type' => true,
218 229 'allOf' => true,
219 - ],
220 - 'anyOf' => [
221 - 'type' => true,
230 + ),
231 + 'anyOf' => array(
232 + 'type' => true,
222 233 'anyOf' => true,
223 - ],
224 - 'not' => [
234 + ),
235 + 'not' => array(
225 236 'type' => true,
226 - 'not' => true,
227 - ],
228 - 'if' => [
237 + 'not' => true,
238 + ),
239 + 'if' => array(
229 240 'type' => true,
230 - 'if' => true,
231 - ],
232 - 'then' => [
241 + 'if' => true,
242 + ),
243 + 'then' => array(
233 244 'type' => true,
234 245 'then' => true,
235 - ],
236 - 'else' => [
246 + ),
247 + 'else' => array(
237 248 'type' => true,
238 249 'else' => true,
239 - ],
240 - 'format' => [
241 - 'type' => true,
250 + ),
251 + 'format' => array(
252 + 'type' => true,
242 253 'format' => true,
243 - ],
244 - 'title' => true,
254 + ),
255 + 'title' => true,
245 256 'description' => true,
246 - 'default' => true,
247 - 'examples' => true,
248 - '$ref' => true,
249 - '$id' => true,
250 - '$schema' => true,
251 - // Adding Lottie-specific keys
252 - 'v' => true,
253 - 'meta' => true,
254 - 'fr' => true,
255 - 'ip' => true,
256 - 'op' => true,
257 - 'w' => true,
258 - 'h' => true,
259 - 'nm' => true,
260 - 'ddd' => true,
261 - 'assets' => true,
262 - 'layers' => true,
263 - 'markers' => true,
264 - ];
265 -
266 - return apply_filters('table_builder_allowed_json_attrs_tags', $allowed_json_tags);
257 + 'default' => true,
258 + 'examples' => true,
259 + '$ref' => true,
260 + '$id' => true,
261 + '$schema' => true,
262 + // Adding Lottie-specific keys.
263 + 'v' => true,
264 + 'meta' => true,
265 + 'fr' => true,
266 + 'ip' => true,
267 + 'op' => true,
268 + 'w' => true,
269 + 'h' => true,
270 + 'nm' => true,
271 + 'ddd' => true,
272 + 'assets' => true,
273 + 'layers' => true,
274 + 'markers' => true,
275 + );
276 +
277 + /**
278 + * Filters the allowed JSON Schema/Lottie attribute keys used when sanitizing block output.
279 + *
280 + * @since Unknown
281 + *
282 + * @param array $allowed_json_tags Allowed JSON keys, keyed by key name.
283 + */
284 + return apply_filters( 'table_builder_allowed_json_attrs_tags', $allowed_json_tags );
267 285 }
268 286
287 + /**
288 + * Returns the allowed HTML tags and attributes for the iframe element.
289 + *
290 + * @return array The allowed HTML tags and attributes.
291 + */
269 292 public static function iframe_allowed_html() {
270 293 return array(
271 294 'iframe' => array(
272 - 'src' => true,
273 - 'name' => true,
274 - 'sandbox' => true,
275 - 'width' => true,
276 - 'height' => true,
277 - 'marginheight' => true,
278 - 'marginwidth' => true,
279 - 'scrolling' => true,
295 + 'src' => true,
296 + 'name' => true,
297 + 'sandbox' => true,
298 + 'width' => true,
299 + 'height' => true,
300 + 'marginheight' => true,
301 + 'marginwidth' => true,
302 + 'scrolling' => true,
280 303 'allowfullscreen' => true,
281 - 'frameborder' => true,
282 - 'title' => true,
283 - 'id' => true,
284 - 'class' => true,
285 - 'style' => true,
286 - 'tabindex' => true,
287 - 'allow' => true,
304 + 'frameborder' => true,
305 + 'title' => true,
306 + 'id' => true,
307 + 'class' => true,
308 + 'style' => true,
309 + 'tabindex' => true,
310 + 'allow' => true,
288 311 ),
289 312 );
290 313 }
291 314
292 - public static function gdc_allowed_html()
293 - {
315 + /**
316 + * Returns the allowed HTML tags and attributes for the "gdc" (GenerateBlocks
317 + * dynamic content) shortcode-style tag used in migrated content.
318 + *
319 + * @return array The allowed HTML tags and attributes.
320 + */
321 + public static function gdc_allowed_html() {
294 322 return array(
295 323 'gdc' => array(
296 - 'selectedpath' => true,
297 - 'class' => true,
298 - 'id' => true,
299 - 'fallback' => true,
300 - 'postcustomfield' => true,
301 - 'postcustomfieldkey' => true,
302 - 'postdatetype' => true,
303 - 'dateformat' => true,
304 - 'customdateformat' => true,
305 - 'excerptlength' => true,
306 - 'tagindex' => true,
307 - 'timetype' => true,
308 - 'timeformat' => true,
309 - 'customtimeformat' => true,
310 - 'categoryindex' => true,
311 - 'nocomment' => true,
312 - 'singlecomment' => true,
313 - 'multicomments' => true,
314 - 'currentdateformat' => true,
324 + 'selectedpath' => true,
325 + 'class' => true,
326 + 'id' => true,
327 + 'fallback' => true,
328 + 'postcustomfield' => true,
329 + 'postcustomfieldkey' => true,
330 + 'postdatetype' => true,
331 + 'dateformat' => true,
332 + 'customdateformat' => true,
333 + 'excerptlength' => true,
334 + 'tagindex' => true,
335 + 'timetype' => true,
336 + 'timeformat' => true,
337 + 'customtimeformat' => true,
338 + 'categoryindex' => true,
339 + 'nocomment' => true,
340 + 'singlecomment' => true,
341 + 'multicomments' => true,
342 + 'currentdateformat' => true,
315 343 'customcurrentdateformat' => true,
316 - 'currenttimeformat' => true,
344 + 'currenttimeformat' => true,
317 345 'customcurrenttimeformat' => true,
318 - 'authorinfo' => true,
319 - 'currentuserinfo' => true,
320 - 'acfgroup' => true,
321 - 'acffield' => true,
346 + 'authorinfo' => true,
347 + 'currentuserinfo' => true,
348 + 'acfgroup' => true,
349 + 'acffield' => true,
322 350 ),
323 351 );
324 352 }
325 353
@@ -330,15 +358,15 @@
330 358 */
331 359 public static function img_allowed_html() {
332 360 return array(
333 361 'img' => array(
334 - 'alt' => true,
335 - 'src' => true,
362 + 'alt' => true,
363 + 'src' => true,
336 364 'srcset' => true,
337 - 'class' => true,
365 + 'class' => true,
338 366 'height' => true,
339 - 'width' => true,
340 - )
367 + 'width' => true,
368 + ),
341 369 );
342 370 }
343 371
344 372 /**
@@ -349,62 +377,69 @@
349 377 public static function style_allowed_html() {
350 378 return array(
351 379 'style' => array(
352 380 'class' => true,
353 - 'id' => true,
354 - )
381 + 'id' => true,
382 + ),
355 383 );
356 384 }
357 385
358 - public static function get_device_list()
359 - {
360 - $default_device_list = [
361 - [
362 - 'label' => 'Desktop',
363 - 'slug' => 'Desktop',
364 - 'value' => 'base',
365 - 'direction' => 'max',
366 - 'isActive' => true,
386 + /**
387 + * Returns the default responsive breakpoint list (Desktop/Tablet/Mobile)
388 + * used across the block editor's responsive controls.
389 + *
390 + * @return array[] List of device descriptors (label/slug/value/direction/isActive/isRequired).
391 + */
392 + public static function get_device_list() {
393 + $default_device_list = array(
394 + array(
395 + 'label' => 'Desktop',
396 + 'slug' => 'Desktop',
397 + 'value' => 'base',
398 + 'direction' => 'max',
399 + 'isActive' => true,
367 400 'isRequired' => true,
368 - ],
369 - [
370 - 'label' => 'Tablet',
371 - 'slug' => 'Tablet',
372 - 'value' => '1024',
373 - 'direction' => 'max',
374 - 'isActive' => true,
401 + ),
402 + array(
403 + 'label' => 'Tablet',
404 + 'slug' => 'Tablet',
405 + 'value' => '1024',
406 + 'direction' => 'max',
407 + 'isActive' => true,
375 408 'isRequired' => true,
376 - ],
377 - [
378 - 'label' => 'Mobile',
379 - 'slug' => 'Mobile',
380 - 'value' => '767',
381 - 'direction' => 'max',
382 - 'isActive' => true,
409 + ),
410 + array(
411 + 'label' => 'Mobile',
412 + 'slug' => 'Mobile',
413 + 'value' => '767',
414 + 'direction' => 'max',
415 + 'isActive' => true,
383 416 'isRequired' => true,
384 - ]
385 - ];
417 + ),
418 + );
386 419
387 420 return $default_device_list;
388 421 }
389 422
390 423 /**
391 - * Adds class to SVG
424 + * Injects a `class="table-builder-icon"` attribute into a raw `<svg ...>` string.
392 425 *
393 426 * @since 1.0.0
394 - * @access public
427 + *
428 + * @param string $svg Raw SVG markup.
429 + * @return string The SVG markup with the class attribute injected, or unchanged if no `<svg` tag is found.
395 430 */
396 431 public static function add_class_to_svg( $svg ) {
397 - $originalString = $svg;
398 - $substringToAdd = "class='table-builder-icon' ";
399 -
400 - $position = strpos( $originalString, '<svg' );
401 -
402 - if ( $position !== false ) {
403 - $svg = substr_replace( $originalString, $substringToAdd, $position + 5, 0 );
432 + $original_string = $svg;
433 + $substring_to_add = "class='table-builder-icon' ";
434 +
435 + $position = strpos( $original_string, '<svg' );
436 +
437 + if ( false !== $position ) {
438 + $svg = substr_replace( $original_string, $substring_to_add, $position + 5, 0 );
404 439 return $svg;
405 440 }
406 -
441 +
407 442 return $svg;
408 443 }
409 444
410 445 /**
@@ -413,26 +448,35 @@
413 448 * This function retrieves the wrapper attributes for a dynamic block.
414 449 * It checks if the function "get_block_wrapper_attributes" exists and if the block is not empty.
415 450 * If both conditions are met, it retrieves the block attributes, including the block ID.
416 451 * It then merges the required attributes with any extra attributes provided.
417 - * Finally, it applies the "roxslider/dynamic_block_wrapper_attributes" filter and returns the wrapper attributes.
452 + * Finally, it applies the "tablebuilder/dynamic_block_wrapper_attributes" filter and returns the wrapper attributes.
418 453 *
419 454 * @param object $block The dynamic block object.
420 - * @param array $extra_attrs Additional attributes to be merged with the required attributes.
455 + * @param array $extra_attrs Additional attributes to be merged with the required attributes.
421 456 * @return string The wrapper attributes for the dynamic block.
422 457 */
423 - public static function get_dynamic_block_wrapper_attributes($block, $extra_attrs = array()) {
424 - if(function_exists("get_block_wrapper_attributes") && !empty($block)) {
425 - $block_attrs = $block->attributes;
426 - $block_id = $block_attrs['blockID'];
458 + public static function get_dynamic_block_wrapper_attributes( $block, $extra_attrs = array() ) {
459 + if ( function_exists( 'get_block_wrapper_attributes' ) && ! empty( $block ) ) {
460 + $block_attrs = $block->attributes;
461 + $block_id = $block_attrs['blockID'];
427 462 $required_attrs = array(
428 - 'id' => 'block-' . $block_id
463 + 'id' => 'block-' . $block_id,
429 464 );
430 - $wrapper_attrs = apply_filters('tablebuilder/dynamic_block_wrapper_attributes', array_merge($required_attrs, $extra_attrs), $block);
431 - return get_block_wrapper_attributes($wrapper_attrs);
465 + /**
466 + * Filters a dynamic block's wrapper attributes before they're rendered.
467 + *
468 + * @since Unknown
469 + *
470 + * @param array $wrapper_attrs Merged required + extra wrapper attributes (e.g. "id").
471 + * @param object $block The dynamic block object.
472 + */
473 + // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores -- slash-namespaced hook name is this plugin's established public API (used by the Pro add-on); renaming would be a breaking change.
474 + $wrapper_attrs = apply_filters( 'tablebuilder/dynamic_block_wrapper_attributes', array_merge( $required_attrs, $extra_attrs ), $block );
475 + return get_block_wrapper_attributes( $wrapper_attrs );
432 476 }
433 477 }
434 -
478 +
435 479 /**
436 480 * Extends the allowed HTML tags for post content.
437 481 *
438 482 * @return array The extended array of allowed HTML tags.
@@ -445,46 +489,48 @@
445 489 return $post_allowed_html;
446 490 }
447 491
448 492 /**
449 - * Retrieves the settings from the specified key in the options table.
493 + * Retrieves the plugin's settings, or a specific key/field/inner-field within them,
494 + * from the "table_builder_settings_list" option.
450 495 *
451 - * @param string $key The key of the settings in the options table.
452 - * @param string $list Optional. The specific list within the settings to retrieve.
453 - * @param string $option Optional. The specific option within the list to retrieve.
454 - * @return mixed The retrieved settings, or false if the list or option is not found.
496 + * @param string $key Optional. Top-level settings key to look up.
497 + * @param string $field Optional. Field within that key to look up; defaults to "status"
498 + * (returned as a bool, true when its value is "active").
499 + * @param string $inner_field Optional. Nested field within $field to look up.
500 + * @return mixed The retrieved settings value, or false if not found.
455 501 */
456 - public static function get_settings($key = '', $field = 'status', $inner_field = '' ) {
502 + public static function get_settings( $key = '', $field = 'status', $inner_field = '' ) {
457 503 $settings = get_option( 'table_builder_settings_list' );
458 504
459 - // check if $key & $field both empty
460 - if ( empty($key) && empty($field) ) {
505 + // check if $key & $field both empty.
506 + if ( empty( $key ) && empty( $field ) ) {
461 507 return $settings;
462 508 }
463 -
464 - // check for primary key
465 - if ( !empty($key) && !empty($settings[$key]) ) {
466 - $settings = $settings[$key];
509 +
510 + // check for primary key.
511 + if ( ! empty( $key ) && ! empty( $settings[ $key ] ) ) {
512 + $settings = $settings[ $key ];
467 513 }
468 514
469 - // check for primary field
470 - if( !empty($field) ) {
471 - if( $field === 'status' && !empty($settings[$field]) ) {
472 - return ($settings[$field] === 'active') ? true : false;
515 + // check for primary field.
516 + if ( ! empty( $field ) ) {
517 + if ( 'status' === $field && ! empty( $settings[ $field ] ) ) {
518 + return ( 'active' === $settings[ $field ] ) ? true : false;
473 519 } else {
474 - $settings = !empty($settings[$field]) ? $settings[$field] : false;
520 + $settings = ! empty( $settings[ $field ] ) ? $settings[ $field ] : false;
475 521 }
476 522 }
477 523
478 - // check for inner field
479 - if( !empty($inner_field) ) {
480 - if( isset($settings[$inner_field]['value']) ) {
481 - $settings = $settings[$inner_field]['value'];
524 + // check for inner field.
525 + if ( ! empty( $inner_field ) ) {
526 + if ( isset( $settings[ $inner_field ]['value'] ) ) {
527 + $settings = $settings[ $inner_field ]['value'];
482 528 } else {
483 - $settings = !empty($settings[$inner_field]) ? $settings[$inner_field] : false;
529 + $settings = ! empty( $settings[ $inner_field ] ) ? $settings[ $inner_field ] : false;
484 530 }
485 531 }
486 -
532 +
487 533 return $settings;
488 534 }
489 535
490 536 /**
@@ -493,102 +539,118 @@
493 539 * @param mixed $key The key used to determine the border value.
494 540 * @return array An array representing the border value. The array contains the following keys:
495 541 * - 'border': The border value, or null if the key is null.
496 542 */
497 - public static function get_border_value($key) {
498 -
499 -
500 - if (!is_array($key)) {
501 - return ['border' => null];
543 + public static function get_border_value( $key ) {
544 +
545 + if ( ! is_array( $key ) ) {
546 + return array( 'border' => null );
502 547 }
503 -
504 - $keyLength = count($key);
505 548
549 + // Per-side border box: keys are direction names (top/right/bottom/left),
550 + // each holding its own {width, style, color}.
551 + $sides = array( 'top', 'right', 'bottom', 'left' );
552 + $is_per_side = count( array_intersect( array_keys( $key ), $sides ) ) > 0;
506 553
507 - if ($keyLength < 3) {
508 - $properties = ['style', 'color', 'width'];
509 - $borderParts = [];
510 -
511 - foreach ($properties as $property) {
512 - if (isset($key[$property])) {
513 - $borderParts[] = $key[$property];
554 + if ( $is_per_side ) {
555 + $border = array();
556 + foreach ( $key as $direction => $value ) {
557 + if ( ! is_array( $value ) ) {
558 + continue;
514 559 }
560 + if ( isset( $value['width'] ) && '' !== $value['width'] ) {
561 + $color = ! empty( $value['color'] ) ? $value['color'] : 'currentColor';
562 + $style = ! empty( $value['style'] ) ? $value['style'] : 'solid';
563 + $border[ "border-{$direction}" ] = "{$value['width']} {$style} {$color}";
564 + }
515 565 }
566 + return $border;
567 + }
516 568
517 -
518 - return ['border' => implode(' ', $borderParts)];
519 -
569 + // Flat border: a defined width alone is enough to emit a declaration —
570 + // this ensures an explicit 0 always produces `border-width: 0` instead
571 + // of being silently dropped when style/color weren't also set (which
572 + // let a theme's/Elementor's default table border show through).
573 + if ( isset( $key['width'] ) && '' !== $key['width'] ) {
574 + $color = ! empty( $key['color'] ) ? $key['color'] : 'currentColor';
575 + $style = ! empty( $key['style'] ) ? $key['style'] : 'solid';
576 + return array( 'border' => "{$key['width']} {$style} {$color}" );
520 577 }
521 -
522 -
523 - if ($keyLength === 3) {
524 - if (isset($key['style'])) {
525 - return ['border' => "{$key['width']} {$key['style']} {$key['color']}"];
526 - }
578 +
579 + if ( ! empty( $key['color'] ) ) {
580 + $style = ! empty( $key['style'] ) ? $key['style'] : 'solid';
581 + return array( 'border' => "1px {$style} {$key['color']}" );
527 582 }
528 -
529 - if ($keyLength === 4 || $keyLength === 3) {
530 - $border = [];
531 - foreach ($key as $direction => $value) {
532 - if (isset($value['style'])) {
533 - $border["border-{$direction}"] = "{$value['width']} {$value['style']} {$value['color']}";
534 - }
535 - }
536 - return $border;
537 - }
583 +
584 + return array( 'border' => null );
538 585 }
539 586
540 587 /**
541 - * get box value
542 - *
543 - * Similar to getBoxValue in roxslider js helper
544 - * @param array $key
545 - * @param string $property
588 + * Builds a CSS box-model value (margin/padding/border-radius style) from a
589 + * {top,right,bottom,left} array, collapsing to a shorthand string when all
590 + * four sides share values.
591 + *
592 + * @param array $key Box values keyed by 'top'/'right'/'bottom'/'left'.
593 + * @param string $property CSS property prefix (e.g. "margin", "padding"), or
594 + * "border-radius" for the corner-radius longhand variant.
595 + * @return array CSS declarations keyed by property name (shorthand or per-side longhand).
546 596 */
547 - public static function get_box_value($key = [], $property = "") {
548 - $top = isset($key['top']) ? $key['top'] : null;
549 - $right = isset($key['right']) ? $key['right'] : null;
550 - $bottom = isset($key['bottom']) ? $key['bottom'] : null;
551 - $left = isset($key['left']) ? $key['left'] : null;
597 + public static function get_box_value( $key = array(), $property = '' ) {
598 + $top = isset( $key['top'] ) ? $key['top'] : null;
599 + $right = isset( $key['right'] ) ? $key['right'] : null;
600 + $bottom = isset( $key['bottom'] ) ? $key['bottom'] : null;
601 + $left = isset( $key['left'] ) ? $key['left'] : null;
552 602
553 - $boxObject = ['top' => $top, 'right' => $right, 'bottom' => $bottom, 'left' => $left];
554 - $count = count(array_filter($boxObject, function ($value) {
555 - return $value !== null;
556 - }));
603 + $box_object = array(
604 + 'top' => $top,
605 + 'right' => $right,
606 + 'bottom' => $bottom,
607 + 'left' => $left,
608 + );
609 + $count = count(
610 + array_filter(
611 + $box_object,
612 + function ( $value ) {
613 + return null !== $value;
614 + }
615 + )
616 + );
557 617
558 - if ($count === 0) return [$property => null];
618 + if ( 0 === $count ) {
619 + return array( $property => null );
620 + }
559 621
560 - if ($count === 4) {
561 - $boxValues = '';
622 + if ( 4 === $count ) {
623 + $box_values = '';
562 624
563 - if ($top === $bottom && $top === $right && $top === $left) {
564 - $boxValues = $top;
565 - } elseif ($top === $bottom && $left === $right) {
566 - $boxValues = "{$top} {$right}";
625 + if ( $top === $bottom && $top === $right && $top === $left ) {
626 + $box_values = $top;
627 + } elseif ( $top === $bottom && $left === $right ) {
628 + $box_values = "{$top} {$right}";
567 629 } else {
568 - $boxValues = "{$top} {$right} {$bottom} {$left}";
630 + $box_values = "{$top} {$right} {$bottom} {$left}";
569 631 }
570 632
571 - return [$property => $boxValues];
633 + return array( $property => $box_values );
572 634 }
573 635
574 - $finalBox = [];
636 + $final_box = array();
575 637
576 - if ($property !== "border-radius") {
577 - foreach ($boxObject as $direction => $value) {
578 - $finalBox["{$property}-{$direction}"] = isset($key[$direction]) ? $key[$direction] : null;
638 + if ( 'border-radius' !== $property ) {
639 + foreach ( $box_object as $direction => $value ) {
640 + $final_box[ "{$property}-{$direction}" ] = isset( $key[ $direction ] ) ? $key[ $direction ] : null;
579 641 }
580 642
581 - return $finalBox;
643 + return $final_box;
582 644 }
583 645
584 - if ($property === "border-radius") {
585 - $finalBox["border-top-left-radius"] = $top;
586 - $finalBox["border-top-right-radius"] = $right;
587 - $finalBox["border-bottom-right-radius"] = $bottom;
588 - $finalBox["border-bottom-left-radius"] = $left;
646 + if ( 'border-radius' === $property ) {
647 + $final_box['border-top-left-radius'] = $top;
648 + $final_box['border-top-right-radius'] = $right;
649 + $final_box['border-bottom-right-radius'] = $bottom;
650 + $final_box['border-bottom-left-radius'] = $left;
589 651
590 - return $finalBox;
652 + return $final_box;
591 653 }
592 654 }
593 655
594 656 /**
@@ -597,150 +659,157 @@
597 659 * @param string $type The type of color to retrieve. Can be either 'gradient' or 'color'.
598 660 * @param string $color The color value.
599 661 * @return string The retrieved color.
600 662 */
601 - public static function get_color($type, $color) {
663 + public static function get_color( $type, $color ) {
602 664
603 - if (empty($color) || strpos($color, "linear-gradient(") === 0 || strpos($color, "radial-gradient(") === 0 || strpos($color, '#') === 0) {
665 + if ( empty( $color ) || 0 === strpos( $color, 'linear-gradient(' ) || 0 === strpos( $color, 'radial-gradient(' ) || 0 === strpos( $color, '#' ) ) {
604 666 return $color;
605 667 }
606 -
607 - $color_parts = explode(',', $color, 2);
608 -
609 668
669 + $color_parts = explode( ',', $color, 2 );
670 +
610 671 $color_parts1 = $color_parts[0];
611 672 $color_parts2 = $color_parts[1];
612 673
613 - $bg_color = "";
674 + $bg_color = '';
614 675
615 - if($type == 'gradient'){
616 - $bg_color = "var(--wp--preset--gradient--".$color_parts1.",".$color_parts2.")";
617 -
676 + if ( 'gradient' === $type ) {
677 + $bg_color = 'var(--wp--preset--gradient--' . $color_parts1 . ',' . $color_parts2 . ')';
678 +
618 679 } else {
619 - $bg_color = "var(--wp--preset--color--".$color_parts1.",". $color_parts2.")";
680 + $bg_color = 'var(--wp--preset--color--' . $color_parts1 . ',' . $color_parts2 . ')';
620 681 }
621 682 return $bg_color;
622 683 }
623 684
624 685 /**
625 - * fill_background_generator
626 - *
627 - * Similar to fillBackgroundGenerator in roxSlider js helper
628 - *
629 - * @param array $background
630 - * @param string $device
686 + * Builds CSS background-* declarations (color, gradient, or image with
687 + * position/size/repeat/attachment) from a block's background attribute object.
688 + *
689 + * @param array $background Background attribute object (backgroundType plus the
690 + * relevant color/gradient/image sub-fields).
691 + * @param string $device Responsive device key used for position/size sub-fields; default "Desktop".
692 + * @return array CSS declarations keyed by "background-*" property name.
631 693 */
632 - public static function fill_background_generator($background, $device = "Desktop") {
633 -
634 - $fillBackground = [
694 + public static function fill_background_generator( $background, $device = 'Desktop' ) {
695 +
696 + $fill_background = array(
635 697 'background-image' => '',
636 - ];
698 + );
637 699
638 - if (isset($background['backgroundType']) && $background['backgroundType'] === 'classic') {
639 - $fillBackground['background-color'] = isset($background['backgroundColor']) ? self::get_color('color', $background['backgroundColor']) : '';
700 + if ( isset( $background['backgroundType'] ) && 'classic' === $background['backgroundType'] ) {
701 + $fill_background['background-color'] = isset( $background['backgroundColor'] ) ? self::get_color( 'color', $background['backgroundColor'] ) : '';
640 702 }
641 703
642 - if (isset($background['backgroundType']) && $background['backgroundType'] === 'gradient' && !empty($background['gradient'])) {
643 -
644 - $fillBackground['background-image'] = isset($background['gradient']) ? (self::get_color('gradient',$background['gradient']) ?? '') : '';
704 + if ( isset( $background['backgroundType'] ) && 'gradient' === $background['backgroundType'] && ! empty( $background['gradient'] ) ) {
705 +
706 + $fill_background['background-image'] = isset( $background['gradient'] ) ? ( self::get_color( 'gradient', $background['gradient'] ) ?? '' ) : '';
645 707 }
646 708
647 - if (isset($background['backgroundType']) && $background['backgroundType'] === 'image' && !empty($background['backgroundImage'])) {
648 - if (!empty($background['backgroundImage']['imageUrl'])) {
649 - $fillBackground['background-image'] = "url({$background['backgroundImage']['imageUrl']})";
709 + if ( isset( $background['backgroundType'] ) && 'image' === $background['backgroundType'] && ! empty( $background['backgroundImage'] ) ) {
710 + if ( ! empty( $background['backgroundImage']['imageUrl'] ) ) {
711 + $fill_background['background-image'] = "url({$background['backgroundImage']['imageUrl']})";
650 712 }
651 713
652 - if (!empty($background['backgroundAttachment'])) {
653 - $fillBackground['background-attachment'] = $background['backgroundAttachment'];
714 + if ( ! empty( $background['backgroundAttachment'] ) ) {
715 + $fill_background['background-attachment'] = $background['backgroundAttachment'];
654 716 }
655 717
656 - if (!empty($background['backgroundPosition'][$device]) && $background['backgroundPosition'][$device] !== "custom") {
657 - $fillBackground['background-position'] = $background['backgroundPosition'][$device];
718 + if ( ! empty( $background['backgroundPosition'][ $device ] ) && 'custom' !== $background['backgroundPosition'][ $device ] ) {
719 + $fill_background['background-position'] = $background['backgroundPosition'][ $device ];
658 720 }
659 721
660 722 if (
661 - !empty($background['backgroundPosition'][$device]) && $background['backgroundPosition'][$device] === "custom" &&
662 - !empty($background['customPositionX'][$device]) && !empty($background['customPositionY'][$device])
723 + ! empty( $background['backgroundPosition'][ $device ] ) && 'custom' === $background['backgroundPosition'][ $device ] &&
724 + ! empty( $background['customPositionX'][ $device ] ) && ! empty( $background['customPositionY'][ $device ] )
663 725 ) {
664 - $fillBackground['background-position'] = self::get_slider_value($background['customPositionX'][$device]) . ' ' . self::get_slider_value($background['customPositionY'][$device]);
726 + $fill_background['background-position'] = self::get_slider_value( $background['customPositionX'][ $device ] ) . ' ' . self::get_slider_value( $background['customPositionY'][ $device ] );
665 727 }
666 728
667 - if (!empty($background['backgroundSize']) && $background['backgroundSize'] !== "custom") {
668 - $fillBackground['background-size'] = $background['backgroundSize'];
729 + if ( ! empty( $background['backgroundSize'] ) && 'custom' !== $background['backgroundSize'] ) {
730 + $fill_background['background-size'] = $background['backgroundSize'];
669 731 }
670 732
671 733 if (
672 - !empty($background['backgroundSize']) && $background['backgroundSize'] === "custom" &&
673 - !empty($background['customSize'][$device])
734 + ! empty( $background['backgroundSize'] ) && 'custom' === $background['backgroundSize'] &&
735 + ! empty( $background['customSize'][ $device ] )
674 736 ) {
675 - $fillBackground['background-size'] = self::get_slider_value($background['customSize'][$device]) . ' auto';
737 + $fill_background['background-size'] = self::get_slider_value( $background['customSize'][ $device ] ) . ' auto';
676 738 }
677 739
678 - if (!empty($background['backgroundRepeat'])) {
679 - $fillBackground['background-repeat'] = $background['backgroundRepeat'];
740 + if ( ! empty( $background['backgroundRepeat'] ) ) {
741 + $fill_background['background-repeat'] = $background['backgroundRepeat'];
680 742 }
681 743 }
682 744
683 - return $fillBackground;
745 + return $fill_background;
684 746 }
685 747
686 748 /**
687 - * get_typography_value
688 - *
689 - * Similar to getTypographyValue in roxSlider js helper
749 + * Builds CSS font-, text-, line-height, letter-spacing, and word-spacing
750 + * declarations from a typography attribute object for the given responsive device.
751 + *
752 + * @param array $key Typography attribute object (fontFamily/fontSize/fontStyle/
753 + * fontWeight/textDecoration/textTransform/lineHeight/letterSpacing/wordSpacing).
754 + * @param string $device Responsive device key (e.g. "Desktop"); non-Desktop devices
755 + * omit font-family/style/weight/text-decoration/text-transform,
756 + * which are treated as desktop-only.
757 + * @return array CSS declarations keyed by property name.
690 758 */
691 - public static function get_typography_value($key, $device) {
692 - if ($device === 'Desktop') {
693 - return [
694 - 'font-family' => isset($key['fontFamily']['value']) ? $key['fontFamily']['value'] : null,
695 - 'font-size' => isset($key['fontSize'][$device]['size']) && isset($key['fontSize'][$device]['unit'])
696 - ? $key['fontSize'][$device]['size'] . $key['fontSize'][$device]['unit']
759 + public static function get_typography_value( $key, $device ) {
760 + if ( 'Desktop' === $device ) {
761 + return array(
762 + 'font-family' => isset( $key['fontFamily']['value'] ) ? $key['fontFamily']['value'] : null,
763 + 'font-size' => isset( $key['fontSize'][ $device ]['size'] ) && isset( $key['fontSize'][ $device ]['unit'] )
764 + ? $key['fontSize'][ $device ]['size'] . $key['fontSize'][ $device ]['unit']
697 765 : null,
698 - 'font-style' => isset($key['fontStyle']) ? $key['fontStyle'] : null,
699 - 'font-weight' => isset($key['fontWeight']['value']) ? $key['fontWeight']['value'] : null,
700 - 'text-decoration' => isset($key['textDecoration']) ? $key['textDecoration'] : null,
701 - 'text-transform' => isset($key['textTransform']) ? $key['textTransform'] : null,
702 - 'line-height' => isset($key['lineHeight'][$device]['size']) && isset($key['lineHeight'][$device]['unit'])
703 - ? $key['lineHeight'][$device]['size'] . $key['lineHeight'][$device]['unit']
766 + 'font-style' => isset( $key['fontStyle'] ) ? $key['fontStyle'] : null,
767 + 'font-weight' => isset( $key['fontWeight']['value'] ) ? $key['fontWeight']['value'] : null,
768 + 'text-decoration' => isset( $key['textDecoration'] ) ? $key['textDecoration'] : null,
769 + 'text-transform' => isset( $key['textTransform'] ) ? $key['textTransform'] : null,
770 + 'line-height' => isset( $key['lineHeight'][ $device ]['size'] ) && isset( $key['lineHeight'][ $device ]['unit'] )
771 + ? $key['lineHeight'][ $device ]['size'] . $key['lineHeight'][ $device ]['unit']
704 772 : null,
705 - 'letter-spacing' => isset($key['letterSpacing'][$device]['size']) && isset($key['letterSpacing'][$device]['unit'])
706 - ? $key['letterSpacing'][$device]['size'] . $key['letterSpacing'][$device]['unit']
773 + 'letter-spacing' => isset( $key['letterSpacing'][ $device ]['size'] ) && isset( $key['letterSpacing'][ $device ]['unit'] )
774 + ? $key['letterSpacing'][ $device ]['size'] . $key['letterSpacing'][ $device ]['unit']
707 775 : null,
708 - 'word-spacing' => isset($key['wordSpacing'][$device]['size']) && isset($key['wordSpacing'][$device]['unit'])
709 - ? $key['wordSpacing'][$device]['size'] . $key['wordSpacing'][$device]['unit']
776 + 'word-spacing' => isset( $key['wordSpacing'][ $device ]['size'] ) && isset( $key['wordSpacing'][ $device ]['unit'] )
777 + ? $key['wordSpacing'][ $device ]['size'] . $key['wordSpacing'][ $device ]['unit']
710 778 : null,
711 - ];
779 + );
712 780 } else {
713 - return [
714 - 'font-size' => isset($key['fontSize'][$device]['size']) && isset($key['fontSize'][$device]['unit'])
715 - ? $key['fontSize'][$device]['size'] . $key['fontSize'][$device]['unit']
781 + return array(
782 + 'font-size' => isset( $key['fontSize'][ $device ]['size'] ) && isset( $key['fontSize'][ $device ]['unit'] )
783 + ? $key['fontSize'][ $device ]['size'] . $key['fontSize'][ $device ]['unit']
716 784 : null,
717 - 'line-height' => isset($key['lineHeight'][$device]['size']) && isset($key['lineHeight'][$device]['unit'])
718 - ? $key['lineHeight'][$device]['size'] . $key['lineHeight'][$device]['unit']
785 + 'line-height' => isset( $key['lineHeight'][ $device ]['size'] ) && isset( $key['lineHeight'][ $device ]['unit'] )
786 + ? $key['lineHeight'][ $device ]['size'] . $key['lineHeight'][ $device ]['unit']
719 787 : null,
720 - 'letter-spacing' => isset($key['letterSpacing'][$device]['size']) && isset($key['letterSpacing'][$device]['unit'])
721 - ? $key['letterSpacing'][$device]['size'] . $key['letterSpacing'][$device]['unit']
788 + 'letter-spacing' => isset( $key['letterSpacing'][ $device ]['size'] ) && isset( $key['letterSpacing'][ $device ]['unit'] )
789 + ? $key['letterSpacing'][ $device ]['size'] . $key['letterSpacing'][ $device ]['unit']
722 790 : null,
723 - 'word-spacing' => isset($key['wordSpacing'][$device]['size']) && isset($key['wordSpacing'][$device]['unit'])
724 - ? $key['wordSpacing'][$device]['size'] . $key['wordSpacing'][$device]['unit']
791 + 'word-spacing' => isset( $key['wordSpacing'][ $device ]['size'] ) && isset( $key['wordSpacing'][ $device ]['unit'] )
792 + ? $key['wordSpacing'][ $device ]['size'] . $key['wordSpacing'][ $device ]['unit']
725 793 : null,
726 - ];
794 + );
727 795 }
728 796 }
729 -
797 +
730 798 /**
731 - * get slider value
732 - *
733 - * Similar to getSliderValue function in JS helper
734 - * @param string $value
735 - * @return string
799 + * Gets slider value.
800 + *
801 + * Similar to getSliderValue function in JS helper.
802 + *
803 + * @param array $key Slider value array with "size" and "unit" keys.
804 + * @return string|null The combined "{size}{unit}" string, or null if no size is set.
736 805 */
737 - public static function get_slider_value($key) {
806 + public static function get_slider_value( $key ) {
738 807 $value = '';
739 808
740 - if (!empty($key['size']) && !empty($key['unit'])) {
809 + if ( ! empty( $key['size'] ) && ! empty( $key['unit'] ) ) {
741 810 $value = $key['size'] . $key['unit'];
742 - } elseif (!empty($key['size']) && empty($key['unit'])) {
811 + } elseif ( ! empty( $key['size'] ) && empty( $key['unit'] ) ) {
743 812 $value = $key['size'];
744 813 } else {
745 814 $value = null;
746 815 }
@@ -748,71 +817,95 @@
748 817 return $value;
749 818 }
750 819
751 820 /**
752 - * parse css
753 - *
754 - * @param string $css
755 - * @return string
821 + * Converts a per-device map of {selector, ...cssValues} style records into
822 + * per-device CSS text blocks.
823 + *
824 + * @param array $raw_css Style records keyed by device slug (desktop/tablet/mobile/etc.),
825 + * each an array of {selector, ...property=>value} entries.
826 + * @return array<string,string> Compiled CSS text keyed by device slug.
756 827 */
757 - public static function parse_css($raw_css) {
758 -
759 - $styles = [];
760 - $device_list = ['desktop', 'tablet', 'mobile', 'tabletlandscape', 'mobilelandscape', 'laptop', 'widescreen'];
828 + public static function parse_css( $raw_css ) {
761 829
762 - foreach ($device_list as $device) {
763 - $deviceStyles = $raw_css[$device] ?? [];
830 + $styles = array();
831 + $device_list = array( 'desktop', 'tablet', 'mobile', 'tabletlandscape', 'mobilelandscape', 'laptop', 'widescreen' );
764 832
765 - $styles[$device] = array_map(function ($style) {
766 - if (!is_array($style) || !isset($style['selector'])) {
767 - return '';
768 - }
833 + foreach ( $device_list as $device ) {
834 + $device_styles = $raw_css[ $device ] ?? array();
769 835
770 - $selector = $style['selector'];
771 - $cssValues = array_filter($style, function ($value, $key) {
772 - return $key !== 'selector' && $value !== null && $value !== '' && !is_numeric($value) && !in_array($value, ['px', 'em', 'rem', '%', 'vh', 'vw']) && strpos($value, 'undefined') === false;
773 - }, ARRAY_FILTER_USE_BOTH);
836 + $styles[ $device ] = array_map(
837 + function ( $style ) {
838 + if ( ! is_array( $style ) || ! isset( $style['selector'] ) ) {
839 + return '';
840 + }
774 841
775 - if (empty($cssValues)) {
776 - return '';
777 - }
842 + $selector = $style['selector'];
843 + $css_values = array_filter(
844 + $style,
845 + function ( $value, $key ) {
846 + return 'selector' !== $key && null !== $value && '' !== $value && ! is_numeric( $value ) && ! in_array( $value, array( 'px', 'em', 'rem', '%', 'vh', 'vw' ), true ) && false === strpos( $value, 'undefined' );
847 + },
848 + ARRAY_FILTER_USE_BOTH
849 + );
778 850
779 - return "{$selector} { " . implode(' ', array_map(function ($key, $value) {
780 - return "{$key}: {$value};";
781 - }, array_keys($cssValues), $cssValues)) . " }";
782 - }, $deviceStyles);
851 + if ( empty( $css_values ) ) {
852 + return '';
853 + }
854 +
855 + return "{$selector} { " . implode(
856 + ' ',
857 + array_map(
858 + function ( $key, $value ) {
859 + return "{$key}: {$value};";
860 + },
861 + array_keys( $css_values ),
862 + $css_values
863 + )
864 + ) . ' }';
865 + },
866 + $device_styles
867 + );
783 868 }
784 -
785 - $device_styles = array_map(function ($style) {
786 - return implode("\n", $style);
787 - }, $styles);
788 869
870 + $device_styles = array_map(
871 + function ( $style ) {
872 + return implode( "\n", $style );
873 + },
874 + $styles
875 + );
876 +
789 877 return $device_styles;
790 878 }
791 879
792 880 /**
793 - * Check if the block is a roxSlider block.
794 - *
795 - * @param string $attrs
796 - * @return bool
881 + * Checks whether a parsed block is one of this plugin's "tablebuilder/*" blocks,
882 + * optionally requiring a specific (possibly nested) attribute to be present.
883 + *
884 + * @param string $block_content Rendered block HTML content.
885 + * @param array $parsed_block Parsed block array (as passed to a `render_block` callback).
886 + * @param string $attrs Optional. Top-level attribute key to require.
887 + * @param string $attrs2 Optional. Nested key within $attrs to require.
888 + * @return bool True if this is a table-builder block matching the given criteria.
797 889 */
798 - public static function is_table_builder_block($block_content, $parsed_block, $attrs = '', $attrs2 = '') {
799 - // Check if $block_content is not empty
800 - $hasBlockContent = !empty($block_content);
801 - // Check if $block['blockName'] is not empty and contains 'roxSlider'
802 - $hasValidBlockName = isset($parsed_block['blockName']) && strpos($parsed_block['blockName'], 'tablebuilder') !== false;
803 -
804 - // Check if $block['attrs']['blockClass'] is not empty
805 - $hasBlockClass = !empty($attrs) && !empty($attrs2)
806 - ? !empty($parsed_block['attrs'][$attrs][$attrs2])
807 - : !empty($parsed_block['attrs'][$attrs] ?? '');
890 + public static function is_table_builder_block( $block_content, $parsed_block, $attrs = '', $attrs2 = '' ) {
891 + // phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- explanatory prose comments, not commented-out code.
892 + // Check if $block_content is not empty.
893 + $has_block_content = ! empty( $block_content );
894 + // Check if $block['blockName'] is not empty and contains 'roxSlider'.
895 + $has_valid_block_name = isset( $parsed_block['blockName'] ) && false !== strpos( $parsed_block['blockName'], 'tablebuilder' );
808 896
809 - if(empty($attrs) && empty($attrs2)) {
810 - $hasBlockClass = true;
897 + // Check if $block['attrs']['blockClass'] is not empty.
898 + $has_block_class = ! empty( $attrs ) && ! empty( $attrs2 )
899 + ? ! empty( $parsed_block['attrs'][ $attrs ][ $attrs2 ] )
900 + : ! empty( $parsed_block['attrs'][ $attrs ] ?? '' );
901 +
902 + if ( empty( $attrs ) && empty( $attrs2 ) ) {
903 + $has_block_class = true;
811 904 }
812 905
813 - // Return true if all conditions are met
814 - return $hasBlockContent && $hasValidBlockName && $hasBlockClass;
906 + // Return true if all conditions are met.
907 + return $has_block_content && $has_valid_block_name && $has_block_class;
815 908 }
816 909
817 910 /**
818 911 * Retrieves the link attributes based on the provided attribute array.
@@ -819,30 +912,32 @@
819 912 *
820 913 * @param array $attribute The attribute array containing the link data.
821 914 * @return string The generated link attributes as a string.
822 915 */
823 - public static function get_link_attributes($attribute) {
824 - if (empty($attribute['url'])) return '';
916 + public static function get_link_attributes( $attribute ) {
917 + if ( empty( $attribute['url'] ) ) {
918 + return '';
919 + }
825 920
826 - $link_data = [];
921 + $link_data = array();
827 922
828 - $link_data['href'] = esc_url($attribute['url'], wp_allowed_protocols());
923 + $link_data['href'] = esc_url( $attribute['url'], wp_allowed_protocols() );
829 924
830 - (isset($attribute['newTab']) && $attribute['newTab']) ? $link_data['target'] = '_blank' : '';
925 + ( isset( $attribute['newTab'] ) && $attribute['newTab'] ) ? $link_data['target'] = '_blank' : '';
831 926
832 - (isset($attribute['noFollow']) && $attribute['noFollow']) ? $link_data['rel'] = "nofollow" : '';
927 + ( isset( $attribute['noFollow'] ) && $attribute['noFollow'] ) ? $link_data['rel'] = 'nofollow' : '';
833 928
834 - if (isset($attribute['customAttributes']) && gettype($attribute['customAttributes']) == 'array') {
835 - foreach ($attribute['customAttributes'] as $key => $value) {
836 - if (!empty($value)) {
837 - $attr_key_value = explode('|', $value);
929 + if ( isset( $attribute['customAttributes'] ) && is_array( $attribute['customAttributes'] ) ) {
930 + foreach ( $attribute['customAttributes'] as $key => $value ) {
931 + if ( ! empty( $value ) ) {
932 + $attr_key_value = explode( '|', $value );
838 933
839 - $attr_key = mb_strtolower($attr_key_value[0]);
934 + $attr_key = mb_strtolower( $attr_key_value[0] );
840 935
841 936 // Not allowed characters are removed.
842 - preg_match('/[-_a-z0-9]+/', $attr_key, $attr_key_matches);
937 + preg_match( '/[-_a-z0-9]+/', $attr_key, $attr_key_matches );
843 938
844 - if (empty($attr_key_matches[0])) {
939 + if ( empty( $attr_key_matches[0] ) ) {
845 940 continue;
846 941 }
847 942
848 943 $attr_key = $attr_key_matches[0];
@@ -847,112 +942,491 @@
847 942
848 943 $attr_key = $attr_key_matches[0];
849 944
850 945 // Javascript events and unescaped href are avoided.
851 - if ('href' === $attr_key || 'on' === substr($attr_key, 0, 2)) {
946 + if ( 'href' === $attr_key || 'on' === substr( $attr_key, 0, 2 ) ) {
852 947 continue;
853 948 }
854 949
855 - if (isset($attr_key_value[1])) {
856 - $attr_value = trim($attr_key_value[1]);
950 + if ( isset( $attr_key_value[1] ) ) {
951 + $attr_value = trim( $attr_key_value[1] );
857 952 } else {
858 953 $attr_value = '';
859 954 }
860 955
861 - $link_data[$attr_key] = $attr_value;
956 + $link_data[ $attr_key ] = $attr_value;
862 957 }
863 958 }
864 959 }
865 960
866 961 $link_attributes = '';
867 - foreach ($link_data as $key => $value) {
868 - $link_attributes .= sprintf('%s="%s" ', $key, esc_attr($value));
962 + foreach ( $link_data as $key => $value ) {
963 + $link_attributes .= sprintf( '%s="%s" ', $key, esc_attr( $value ) );
869 964 }
870 965
871 966 return $link_attributes;
872 967 }
873 968
969 + /**
970 + * Gets the plugin's cached license status ("valid" or "invalid"), based on
971 + * whether both the stored license key and license identifier are set.
972 + *
973 + * @return string "valid" or "invalid".
974 + */
874 975 public static function status() {
875 976
876 - $cached = wp_cache_get('table_builder__license_status');
977 + $cached = wp_cache_get( 'table_builder__license_status' );
877 978
878 - if(false !== $cached) {
979 + if ( false !== $cached ) {
879 980 return $cached;
880 981 }
881 982
882 - $oppai = get_option('__table_builder_oppai__', '');
883 - $key = get_option('__table_builder_license_key__', '');
983 + $oppai = get_option( '__table_builder_oppai__', '' );
984 + $key = get_option( '__table_builder_license_key__', '' );
884 985 $status = 'invalid';
885 986
886 - if($oppai != '' && $key != '') {
987 + if ( '' !== $oppai && '' !== $key ) {
887 988 $status = 'valid';
888 989 }
889 990
890 - wp_cache_set('table_builder__license_status', $status);
991 + wp_cache_set( 'table_builder__license_status', $status );
891 992
892 993 return $status;
893 994 }
894 995
996 + /**
997 + * Checks whether the current request's host's TLD is outside a known list of
998 + * public/commercial TLDs — used as a rough heuristic to detect local/dev
999 + * environments (e.g. `.test`, `.local`, `.localhost`) for license checks.
1000 + *
1001 + * @return bool True if the current host's TLD is NOT in the known public-TLD list
1002 + * (i.e. it looks like a local/dev environment).
1003 + */
895 1004 public static function is_local() {
896 - $valid_domains = [
897 - ".academy", ".accountant", ".accountants", ".actor", ".adult", ".africa", ".agency", ".airforce",
898 - ".apartments", ".app", ".army", ".art", ".asia", ".associates", ".attorney", ".auction", ".audio",
899 - ".auto", ".baby", ".band", ".bar", ".bargains", ".beer", ".berlin", ".best", ".bid", ".bike",
900 - ".bingo", ".bio", ".biz", ".black", ".blackfriday", ".blog", ".blue", ".boston", ".boutique",
901 - ".build", ".builders", ".business", ".buzz", ".cab", ".cafe", ".cam", ".camera", ".camp",
902 - ".capital", ".car", ".cards", ".care", ".careers", ".cars", ".casa", ".cash", ".casino",
903 - ".catering", ".center", ".ceo", ".chat", ".cheap", ".christmas", ".church", ".city", ".claims",
904 - ".cleaning", ".click", ".clinic", ".clothing", ".cloud", ".club", ".coach", ".codes", ".coffee",
905 - ".college", ".com", ".community", ".company", ".computer", ".condos", ".construction",
906 - ".consulting", ".contact", ".contractors", ".cooking", ".cool", ".country", ".coupons",
907 - ".courses", ".credit", ".creditcard", ".cricket", ".cruises", ".cymru", ".cyou", ".dance",
908 - ".date", ".dating", ".day", ".deals", ".degree", ".delivery", ".democrat", ".dental",
909 - ".dentist", ".desi", ".design", ".dev", ".diamonds", ".diet", ".digital", ".direct", ".directory",
910 - ".discount", ".doctor", ".dog", ".domains", ".download", ".earth", ".eco", ".education",
911 - ".email", ".energy", ".engineer", ".engineering", ".enterprises", ".equipment", ".estate",
912 - ".events", ".exchange", ".expert", ".exposed", ".express", ".fail", ".faith", ".family",
913 - ".fans", ".farm", ".fashion", ".feedback", ".film", ".finance", ".financial", ".fish",
914 - ".fishing", ".fit", ".fitness", ".flights", ".florist", ".flowers", ".football", ".forsale",
915 - ".foundation", ".fun", ".fund", ".furniture", ".futbol", ".fyi", ".gallery", ".game", ".games",
916 - ".garden", ".gay", ".gdn", ".gift", ".gifts", ".gives", ".glass", ".global", ".gmbh", ".gold",
917 - ".golf", ".graphics", ".gratis", ".green", ".gripe", ".group", ".guide", ".guitars", ".guru",
918 - ".hamburg", ".haus", ".health", ".healthcare", ".help", ".hiphop", ".hockey", ".holdings",
919 - ".holiday", ".horse", ".host", ".hosting", ".house", ".how", ".icu", ".immo", ".immobilien",
920 - ".inc", ".industries", ".info", ".ink", ".institute", ".insure", ".international", ".investments",
921 - ".irish", ".jetzt", ".jewelry", ".juegos", ".kaufen", ".kim", ".kitchen", ".kiwi", ".krd",
922 - ".kyoto", ".land", ".lat", ".lawyer", ".lease", ".legal", ".lgbt", ".life", ".lighting",
923 - ".limited", ".limo", ".link", ".live", ".llc", ".loan", ".loans", ".lol", ".london", ".love",
924 - ".ltd", ".ltda", ".luxury", ".maison", ".management", ".market", ".marketing", ".mba", ".media",
925 - ".melbourne", ".memorial", ".men", ".menu", ".miami", ".mobi", ".moda", ".moe", ".mom", ".money",
926 - ".monster", ".mortgage", ".movie", ".nagoya", ".name", ".navy", ".net", ".network", ".new",
927 - ".news", ".ninja", ".nyc", ".observer", ".okinawa", ".one", ".onl", ".online", ".org", ".osaka",
928 - ".page", ".paris", ".partners", ".parts", ".party", ".photo", ".photography", ".photos", ".pics",
929 - ".pictures", ".pink", ".pizza", ".place", ".plumbing", ".plus", ".poker", ".porn", ".press",
930 - ".pro", ".productions", ".properties", ".property", ".protection", ".pub", ".racing", ".realty",
931 - ".recipes", ".red", ".rehab", ".reise", ".reisen", ".rent", ".rentals", ".repair", ".report",
932 - ".republican", ".rest", ".restaurant", ".review", ".reviews", ".rip", ".rocks", ".rodeo",
933 - ".run", ".ryukyu", ".sale", ".sarl", ".school", ".schule", ".science", ".security", ".services",
934 - ".sex", ".sexy", ".shiksha", ".shoes", ".shop", ".shopping", ".show", ".singles", ".site",
935 - ".ski", ".soccer", ".social", ".software", ".solar", ".solutions", ".soy", ".space", ".storage",
936 - ".store", ".stream", ".studio", ".study", ".style", ".sucks", ".supplies", ".supply", ".support",
937 - ".surf", ".surgery", ".sydney", ".systems", ".tattoo", ".tax", ".taxi", ".team", ".tech",
938 - ".technology", ".tel", ".tennis", ".theater", ".theatre", ".tienda", ".tips", ".tires", ".today",
939 - ".tokyo", ".tools", ".top", ".tours", ".town", ".toys", ".trade", ".training", ".travel",
940 - ".tube", ".university", ".uno", ".vacations", ".vegas", ".ventures", ".vet", ".viajes", ".video",
941 - ".villas", ".vin", ".vip", ".vision", ".vodka", ".vote", ".voting", ".voto", ".voyage", ".wales",
942 - ".watch", ".webcam", ".website", ".wedding", ".wiki", ".win", ".wine", ".work", ".works",
943 - ".world", ".wtf", ".xn--3ds443g", ".xn--6frz82g", ".xxx", ".xyz", ".yoga", ".yokohama", ".zone"
944 - ];
1005 + $valid_domains = array(
1006 + '.academy',
1007 + '.accountant',
1008 + '.accountants',
1009 + '.actor',
1010 + '.adult',
1011 + '.africa',
1012 + '.agency',
1013 + '.airforce',
1014 + '.apartments',
1015 + '.app',
1016 + '.army',
1017 + '.art',
1018 + '.asia',
1019 + '.associates',
1020 + '.attorney',
1021 + '.auction',
1022 + '.audio',
1023 + '.auto',
1024 + '.baby',
1025 + '.band',
1026 + '.bar',
1027 + '.bargains',
1028 + '.beer',
1029 + '.berlin',
1030 + '.best',
1031 + '.bid',
1032 + '.bike',
1033 + '.bingo',
1034 + '.bio',
1035 + '.biz',
1036 + '.black',
1037 + '.blackfriday',
1038 + '.blog',
1039 + '.blue',
1040 + '.boston',
1041 + '.boutique',
1042 + '.build',
1043 + '.builders',
1044 + '.business',
1045 + '.buzz',
1046 + '.cab',
1047 + '.cafe',
1048 + '.cam',
1049 + '.camera',
1050 + '.camp',
1051 + '.capital',
1052 + '.car',
1053 + '.cards',
1054 + '.care',
1055 + '.careers',
1056 + '.cars',
1057 + '.casa',
1058 + '.cash',
1059 + '.casino',
1060 + '.catering',
1061 + '.center',
1062 + '.ceo',
1063 + '.chat',
1064 + '.cheap',
1065 + '.christmas',
1066 + '.church',
1067 + '.city',
1068 + '.claims',
1069 + '.cleaning',
1070 + '.click',
1071 + '.clinic',
1072 + '.clothing',
1073 + '.cloud',
1074 + '.club',
1075 + '.coach',
1076 + '.codes',
1077 + '.coffee',
1078 + '.college',
1079 + '.com',
1080 + '.community',
1081 + '.company',
1082 + '.computer',
1083 + '.condos',
1084 + '.construction',
1085 + '.consulting',
1086 + '.contact',
1087 + '.contractors',
1088 + '.cooking',
1089 + '.cool',
1090 + '.country',
1091 + '.coupons',
1092 + '.courses',
1093 + '.credit',
1094 + '.creditcard',
1095 + '.cricket',
1096 + '.cruises',
1097 + '.cymru',
1098 + '.cyou',
1099 + '.dance',
1100 + '.date',
1101 + '.dating',
1102 + '.day',
1103 + '.deals',
1104 + '.degree',
1105 + '.delivery',
1106 + '.democrat',
1107 + '.dental',
1108 + '.dentist',
1109 + '.desi',
1110 + '.design',
1111 + '.dev',
1112 + '.diamonds',
1113 + '.diet',
1114 + '.digital',
1115 + '.direct',
1116 + '.directory',
1117 + '.discount',
1118 + '.doctor',
1119 + '.dog',
1120 + '.domains',
1121 + '.download',
1122 + '.earth',
1123 + '.eco',
1124 + '.education',
1125 + '.email',
1126 + '.energy',
1127 + '.engineer',
1128 + '.engineering',
1129 + '.enterprises',
1130 + '.equipment',
1131 + '.estate',
1132 + '.events',
1133 + '.exchange',
1134 + '.expert',
1135 + '.exposed',
1136 + '.express',
1137 + '.fail',
1138 + '.faith',
1139 + '.family',
1140 + '.fans',
1141 + '.farm',
1142 + '.fashion',
1143 + '.feedback',
1144 + '.film',
1145 + '.finance',
1146 + '.financial',
1147 + '.fish',
1148 + '.fishing',
1149 + '.fit',
1150 + '.fitness',
1151 + '.flights',
1152 + '.florist',
1153 + '.flowers',
1154 + '.football',
1155 + '.forsale',
1156 + '.foundation',
1157 + '.fun',
1158 + '.fund',
1159 + '.furniture',
1160 + '.futbol',
1161 + '.fyi',
1162 + '.gallery',
1163 + '.game',
1164 + '.games',
1165 + '.garden',
1166 + '.gay',
1167 + '.gdn',
1168 + '.gift',
1169 + '.gifts',
1170 + '.gives',
1171 + '.glass',
1172 + '.global',
1173 + '.gmbh',
1174 + '.gold',
1175 + '.golf',
1176 + '.graphics',
1177 + '.gratis',
1178 + '.green',
1179 + '.gripe',
1180 + '.group',
1181 + '.guide',
1182 + '.guitars',
1183 + '.guru',
1184 + '.hamburg',
1185 + '.haus',
1186 + '.health',
1187 + '.healthcare',
1188 + '.help',
1189 + '.hiphop',
1190 + '.hockey',
1191 + '.holdings',
1192 + '.holiday',
1193 + '.horse',
1194 + '.host',
1195 + '.hosting',
1196 + '.house',
1197 + '.how',
1198 + '.icu',
1199 + '.immo',
1200 + '.immobilien',
1201 + '.inc',
1202 + '.industries',
1203 + '.info',
1204 + '.ink',
1205 + '.institute',
1206 + '.insure',
1207 + '.international',
1208 + '.investments',
1209 + '.irish',
1210 + '.jetzt',
1211 + '.jewelry',
1212 + '.juegos',
1213 + '.kaufen',
1214 + '.kim',
1215 + '.kitchen',
1216 + '.kiwi',
1217 + '.krd',
1218 + '.kyoto',
1219 + '.land',
1220 + '.lat',
1221 + '.lawyer',
1222 + '.lease',
1223 + '.legal',
1224 + '.lgbt',
1225 + '.life',
1226 + '.lighting',
1227 + '.limited',
1228 + '.limo',
1229 + '.link',
1230 + '.live',
1231 + '.llc',
1232 + '.loan',
1233 + '.loans',
1234 + '.lol',
1235 + '.london',
1236 + '.love',
1237 + '.ltd',
1238 + '.ltda',
1239 + '.luxury',
1240 + '.maison',
1241 + '.management',
1242 + '.market',
1243 + '.marketing',
1244 + '.mba',
1245 + '.media',
1246 + '.melbourne',
1247 + '.memorial',
1248 + '.men',
1249 + '.menu',
1250 + '.miami',
1251 + '.mobi',
1252 + '.moda',
1253 + '.moe',
1254 + '.mom',
1255 + '.money',
1256 + '.monster',
1257 + '.mortgage',
1258 + '.movie',
1259 + '.nagoya',
1260 + '.name',
1261 + '.navy',
1262 + '.net',
1263 + '.network',
1264 + '.new',
1265 + '.news',
1266 + '.ninja',
1267 + '.nyc',
1268 + '.observer',
1269 + '.okinawa',
1270 + '.one',
1271 + '.onl',
1272 + '.online',
1273 + '.org',
1274 + '.osaka',
1275 + '.page',
1276 + '.paris',
1277 + '.partners',
1278 + '.parts',
1279 + '.party',
1280 + '.photo',
1281 + '.photography',
1282 + '.photos',
1283 + '.pics',
1284 + '.pictures',
1285 + '.pink',
1286 + '.pizza',
1287 + '.place',
1288 + '.plumbing',
1289 + '.plus',
1290 + '.poker',
1291 + '.porn',
1292 + '.press',
1293 + '.pro',
1294 + '.productions',
1295 + '.properties',
1296 + '.property',
1297 + '.protection',
1298 + '.pub',
1299 + '.racing',
1300 + '.realty',
1301 + '.recipes',
1302 + '.red',
1303 + '.rehab',
1304 + '.reise',
1305 + '.reisen',
1306 + '.rent',
1307 + '.rentals',
1308 + '.repair',
1309 + '.report',
1310 + '.republican',
1311 + '.rest',
1312 + '.restaurant',
1313 + '.review',
1314 + '.reviews',
1315 + '.rip',
1316 + '.rocks',
1317 + '.rodeo',
1318 + '.run',
1319 + '.ryukyu',
1320 + '.sale',
1321 + '.sarl',
1322 + '.school',
1323 + '.schule',
1324 + '.science',
1325 + '.security',
1326 + '.services',
1327 + '.sex',
1328 + '.sexy',
1329 + '.shiksha',
1330 + '.shoes',
1331 + '.shop',
1332 + '.shopping',
1333 + '.show',
1334 + '.singles',
1335 + '.site',
1336 + '.ski',
1337 + '.soccer',
1338 + '.social',
1339 + '.software',
1340 + '.solar',
1341 + '.solutions',
1342 + '.soy',
1343 + '.space',
1344 + '.storage',
1345 + '.store',
1346 + '.stream',
1347 + '.studio',
1348 + '.study',
1349 + '.style',
1350 + '.sucks',
1351 + '.supplies',
1352 + '.supply',
1353 + '.support',
1354 + '.surf',
1355 + '.surgery',
1356 + '.sydney',
1357 + '.systems',
1358 + '.tattoo',
1359 + '.tax',
1360 + '.taxi',
1361 + '.team',
1362 + '.tech',
1363 + '.technology',
1364 + '.tel',
1365 + '.tennis',
1366 + '.theater',
1367 + '.theatre',
1368 + '.tienda',
1369 + '.tips',
1370 + '.tires',
1371 + '.today',
1372 + '.tokyo',
1373 + '.tools',
1374 + '.top',
1375 + '.tours',
1376 + '.town',
1377 + '.toys',
1378 + '.trade',
1379 + '.training',
1380 + '.travel',
1381 + '.tube',
1382 + '.university',
1383 + '.uno',
1384 + '.vacations',
1385 + '.vegas',
1386 + '.ventures',
1387 + '.vet',
1388 + '.viajes',
1389 + '.video',
1390 + '.villas',
1391 + '.vin',
1392 + '.vip',
1393 + '.vision',
1394 + '.vodka',
1395 + '.vote',
1396 + '.voting',
1397 + '.voto',
1398 + '.voyage',
1399 + '.wales',
1400 + '.watch',
1401 + '.webcam',
1402 + '.website',
1403 + '.wedding',
1404 + '.wiki',
1405 + '.win',
1406 + '.wine',
1407 + '.work',
1408 + '.works',
1409 + '.world',
1410 + '.wtf',
1411 + '.xn--3ds443g',
1412 + '.xn--6frz82g',
1413 + '.xxx',
1414 + '.xyz',
1415 + '.yoga',
1416 + '.yokohama',
1417 + '.zone',
1418 + );
945 1419
946 - $host = !empty($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : '';
1420 + $host = ! empty( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
947 1421
948 - // get the domain
949 - $domain = explode('.', $host);
950 - if(count($domain) >= 2) {
951 - $domain = '.' . $domain[count($domain) - 1];
1422 + // get the domain.
1423 + $domain = explode( '.', $host );
1424 + if ( count( $domain ) >= 2 ) {
1425 + $domain = '.' . $domain[ count( $domain ) - 1 ];
952 1426 } else {
953 1427 $domain = null;
954 1428 }
955 1429
956 - return !in_array($domain, $valid_domains);
1430 + return ! in_array( $domain, $valid_domains, true );
957 1431 }
958 1432 }