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