array( 'type' => 'boolean', 'default' => 1, ), 'spinner_style' => array( 'type' => 'spinner_key', 'default' => 'ring', ), 'spinner_color' => array( 'type' => 'color', 'default' => '#4f46e5', ), 'spinner_secondary' => array( 'type' => 'color', 'default' => '#e0e7ff', ), 'spinner_size' => array( 'type' => 'integer', 'default' => 60, 'min' => 16, 'max' => 240, ), 'overlay_color' => array( 'type' => 'color', 'default' => '#ffffff', ), 'overlay_opacity' => array( 'type' => 'integer', 'default' => 85, 'min' => 0, 'max' => 100, ), 'overlay_blur' => array( 'type' => 'integer', 'default' => 0, 'min' => 0, 'max' => 30, ), 'z_index' => array( 'type' => 'integer', 'default' => 99999, 'min' => 1, 'max' => 2147483647, ), 'fade_out_speed' => array( 'type' => 'integer', 'default' => 400, 'min' => 0, 'max' => 5000, ), 'show_on_external' => array( 'type' => 'boolean', 'default' => 0, ), 'show_on_admin_bar' => array( 'type' => 'boolean', 'default' => 0, ), 'show_on_forms' => array( 'type' => 'boolean', 'default' => 0, ), 'exclude_selectors' => array( 'type' => 'textarea', 'default' => '', ), 'exclude_pages' => array( 'type' => 'textarea', 'default' => '', ), 'min_display_time' => array( 'type' => 'integer', 'default' => 0, 'min' => 0, 'max' => 10000, ), 'custom_css' => array( 'type' => 'css', 'default' => '', ), ); /** * Filter the AeroSpin CSS Loading Spinners settings schema. * * Filtered schema entries must retain the expected structure: * type, default, and optional min/max values. * * @since 1.1.4 * * @param array $schema Settings schema. */ $schema = apply_filters( 'aerospin_css_loading_spinners_settings_schema', $schema ); $schema = apply_filters( 'pure_css_spinners_settings_schema', $schema ); return self::normalize_settings_schema( $schema ); } /** * Normalize the settings schema after filters run. * * This keeps filtered schema entries predictable and prevents invalid * custom types, missing defaults, or reversed numeric ranges from * becoming part of the trusted settings layer. * * @since 1.1.4 * * @param mixed $schema Raw schema value. * @return array */ private static function normalize_settings_schema( $schema ) { if ( ! is_array( $schema ) ) { return array(); } $allowed_types = self::get_allowed_schema_types(); $normalized_schema = array(); foreach ( $schema as $key => $args ) { // Sanitize the setting key to prevent malformed array indexes. $key = sanitize_key( $key ); if ( '' === $key || ! is_array( $args ) ) { continue; } // Assign a fallback type if none is provided. $type = isset( $args['type'] ) ? sanitize_key( $args['type'] ) : 'text'; if ( ! in_array( $type, $allowed_types, true ) ) { $type = 'text'; } $entry = array( 'type' => $type, 'default' => array_key_exists( 'default', $args ) ? $args['default'] : self::get_empty_default_for_type( $type ), ); // Process numeric clamping for integer types. if ( 'integer' === $type ) { $minimum = isset( $args['min'] ) && is_numeric( $args['min'] ) ? (int) $args['min'] : 0; $maximum = isset( $args['max'] ) && is_numeric( $args['max'] ) ? (int) $args['max'] : PHP_INT_MAX; // Swap minimum and maximum ranges if they are accidentally reversed by a filter. if ( $minimum > $maximum ) { $stored_minimum = $minimum; $minimum = $maximum; $maximum = $stored_minimum; } $entry['min'] = $minimum; $entry['max'] = $maximum; // Enforce numeric casting and clamp the default value within the allowed min/max boundaries. $entry['default'] = is_numeric( $entry['default'] ) ? (int) $entry['default'] : $minimum; $entry['default'] = max( $minimum, min( $maximum, $entry['default'] ) ); } elseif ( 'boolean' === $type ) { // Strictly convert booleans to 0 or 1. $entry['default'] = empty( $entry['default'] ) ? 0 : 1; } elseif ( 'color' === $type ) { // Run default colors through the sanitizer immediately. $entry['default'] = self::sanitize_color( $entry['default'], '#ffffff' ); } elseif ( 'spinner_key' === $type ) { $entry['default'] = sanitize_key( self::safe_unslash_scalar( $entry['default'] ) ); if ( '' === $entry['default'] ) { $entry['default'] = 'ring'; } } elseif ( in_array( $type, array( 'textarea', 'css', 'text' ), true ) ) { $entry['default'] = self::safe_unslash_scalar( $entry['default'] ); } $normalized_schema[ $key ] = $entry; } return $normalized_schema; } /** * Get supported schema field types. * * @since 1.1.4 * * @return array */ private static function get_allowed_schema_types() { return array( 'boolean', 'integer', 'color', 'spinner_key', 'textarea', 'css', 'text', ); } /** * Get a safe empty default for a schema type. * * @since 1.1.4 * * @param string $type Schema type. * @return mixed */ private static function get_empty_default_for_type( $type ) { switch ( $type ) { case 'boolean': case 'integer': return 0; case 'color': return '#ffffff'; case 'spinner_key': return 'ring'; case 'textarea': case 'css': case 'text': default: return ''; } } /** * Get default settings. * * Defaults are pulled from the schema, filtered, then normalized again * to prevent invalid filtered values from becoming trusted defaults. * * @since 1.0.0 * * @return array */ public static function get_defaults() { $defaults = self::get_raw_defaults(); /** * Filter default settings. * * Values returned here are normalized before being used. * * @since 1.0.0 * * @param array $defaults Default settings. */ $filtered_defaults = apply_filters( 'pure_css_spinners_default_settings', $defaults ); if ( ! is_array( $filtered_defaults ) ) { $filtered_defaults = $defaults; } return self::normalize_settings_with_defaults( $filtered_defaults, $defaults ); } /** * Get unfiltered raw defaults from the settings schema. * * @since 1.1.4 * * @return array */ private static function get_raw_defaults() { $schema = self::get_settings_schema(); $defaults = array(); // Map schema defaults into a clean key-value array. foreach ( $schema as $key => $args ) { $key = sanitize_key( $key ); if ( '' === $key || ! is_array( $args ) || ! array_key_exists( 'default', $args ) ) { continue; } $defaults[ $key ] = $args['default']; } return $defaults; } /* |-------------------------------------------------------------------------- | SECTION 3: Settings Retrieval and Cache |-------------------------------------------------------------------------- */ /** * Retrieve normalized settings. * * Saved values are merged over defaults and normalized through the * central schema before being returned. * * @since 1.0.0 * * @return array */ public static function get_settings() { // Return cached settings early if available. if ( null !== self::$settings_cache ) { return self::$settings_cache; } // Serve from persistent transient cache if available. $cached_transient = get_transient( 'acls_settings_cache' ); if ( ! is_array( $cached_transient ) || empty( $cached_transient ) ) { $cached_transient = get_transient( 'Pure_CSS_Spinners_settings_cache' ); } if ( is_array( $cached_transient ) && ! empty( $cached_transient ) ) { self::$settings_cache = $cached_transient; return self::$settings_cache; } $defaults = self::get_defaults(); $saved_settings = array(); // Use the defined constant to fetch options. $options_key = defined( 'ACLS_OPTIONS_KEY' ) ? ACLS_OPTIONS_KEY : ( defined( 'AEROSPIN_CSS_LOADING_SPINNERS_OPTIONS_KEY' ) ? AEROSPIN_CSS_LOADING_SPINNERS_OPTIONS_KEY : 'acls_settings' ); $saved_settings = get_option( $options_key, null ); // Backward compatibility: If options are empty or not found, check legacy keys. if ( ! is_array( $saved_settings ) || empty( $saved_settings ) ) { $legacy_keys = array( 'Pure_CSS_Spinners_settings', 'cps_settings' ); foreach ( $legacy_keys as $legacy_key ) { if ( $legacy_key === $options_key ) { continue; } $legacy_val = get_option( $legacy_key, null ); if ( is_array( $legacy_val ) && ! empty( $legacy_val ) ) { $saved_settings = $legacy_val; break; } } } if ( ! is_array( $saved_settings ) ) { $saved_settings = array(); } // Merge retrieved settings with schema defaults. $merged_settings = wp_parse_args( $saved_settings, $defaults ); $settings = self::normalize_settings_with_defaults( $merged_settings, $defaults ); /** * Filter normalized AeroSpin CSS Loading Spinners settings. * * The filtered value is normalized again before being cached. * * @since 1.0.0 * * @param array $settings Normalized settings. */ $filtered_settings = apply_filters( 'aerospin_css_loading_spinners_get_settings', $settings ); $filtered_settings = apply_filters( 'pure_css_spinners_get_settings', $filtered_settings ); if ( ! is_array( $filtered_settings ) ) { $filtered_settings = $settings; } // Final sanitization pass before saving to runtime cache. self::$settings_cache = self::normalize_settings_with_defaults( $filtered_settings, $defaults ); // Store in persistent transient cache (12 hours TTL as verified in diagnostics). set_transient( 'acls_settings_cache', self::$settings_cache, 12 * HOUR_IN_SECONDS ); set_transient( 'Pure_CSS_Spinners_settings_cache', self::$settings_cache, 12 * HOUR_IN_SECONDS ); return self::$settings_cache; } /** * Clear runtime and transient settings caches. * * @since 1.0.0 * * @return void */ public static function clear_cache() { // Clear runtime cache explicitly. self::$settings_cache = null; // Clean up both modern and legacy transient records. delete_transient( 'acls_settings_cache' ); delete_transient( 'AeroSpin_CSS_Loading_Spinners_settings_cache' ); delete_transient( 'Pure_CSS_Spinners_settings_cache' ); delete_transient( 'cp_spinners_settings_cache' ); } /* |-------------------------------------------------------------------------- | SECTION 4: Settings Normalization and Sanitization |-------------------------------------------------------------------------- */ /** * Normalize settings against the default settings. * * @since 1.1.4 * * @param array $settings Raw settings. * @return array */ public static function normalize_settings( $settings ) { return self::normalize_settings_with_defaults( $settings, self::get_defaults() ); } /** * Sanitize settings against the default settings. * * Alias of normalize_settings() for settings save handlers. * * @since 1.1.4 * * @param array $settings Raw settings. * @return array */ public static function sanitize_settings( $settings ) { return self::normalize_settings( $settings ); } /** * Normalize settings with an explicit defaults array. * * @since 1.1.4 * * @param array $settings Raw settings. * @param array $defaults Trusted defaults. * @return array */ private static function normalize_settings_with_defaults( $settings, $defaults ) { $schema = self::get_settings_schema(); $settings = is_array( $settings ) ? $settings : array(); $defaults = is_array( $defaults ) ? $defaults : array(); $normalized = array(); // Iterate through schema rules to sanitize every value individually. foreach ( $schema as $key => $args ) { $key = sanitize_key( $key ); if ( '' === $key || ! is_array( $args ) ) { continue; } $default_value = array_key_exists( $key, $defaults ) ? $defaults[ $key ] : ''; $value = array_key_exists( $key, $settings ) ? $settings[ $key ] : $default_value; $normalized[ $key ] = self::sanitize_setting_value( $key, $value, $default_value, $args ); } return $normalized; } /** * Sanitize a single setting value. * * @since 1.1.4 * * @param string $key Setting key. * @param mixed $value Raw setting value. * @param mixed $default_value Default setting value. * @param array $args Schema arguments. * @return mixed */ private static function sanitize_setting_value( $key, $value, $default_value, $args ) { $type = isset( $args['type'] ) ? sanitize_key( $args['type'] ) : 'text'; // Switch based on predefined schema types. switch ( $type ) { case 'boolean': return empty( $value ) ? 0 : 1; case 'integer': $value = is_numeric( $value ) ? (int) $value : (int) $default_value; if ( isset( $args['min'] ) ) { $value = max( (int) $args['min'], $value ); } if ( isset( $args['max'] ) ) { $value = min( (int) $args['max'], $value ); } return $value; case 'color': return self::sanitize_color( $value, $default_value ); case 'spinner_key': return self::sanitize_spinner_key( $value, $default_value ); case 'textarea': return self::sanitize_textarea_lines( $value ); case 'css': return self::sanitize_custom_css( $value ); case 'text': default: return sanitize_text_field( self::safe_unslash_scalar( $value ) ); } } /** * Safely cast to scalar string without stripping intentional backslashes. * * This avoids warnings if a filtered value or malformed request sends * an array where a scalar string is expected, while preserving valid * selector escapes (e.g. .md\:block) and already-unslashed database values. * * @since 1.1.4 * * @param mixed $value Raw value. * @return string */ private static function safe_unslash_scalar( $value ) { if ( is_array( $value ) || is_object( $value ) ) { return ''; } return is_string( $value ) ? $value : (string) $value; } /** * Sanitize a spinner key. * * @since 1.1.4 * * @param mixed $value Raw spinner key. * @param string $default_value Default spinner key. * @return string */ public static function sanitize_spinner_key( $value, $default_value = 'ring' ) { $value = sanitize_key( self::safe_unslash_scalar( $value ) ); $default_value = sanitize_key( self::safe_unslash_scalar( $default_value ) ); if ( '' === $default_value ) { $default_value = 'ring'; } if ( '' === $value ) { return $default_value; } // Validate against known spinners if the retrieval function exists. if ( function_exists( 'Pure_CSS_Spinners_get_spinners' ) ) { $spinners = Pure_CSS_Spinners_get_spinners(); if ( is_array( $spinners ) && ! array_key_exists( $value, $spinners ) ) { return $default_value; } } return $value; } /** * Sanitize color values. * * Accepts valid hex colors and strict rgba() colors with numeric ranges. * CSS variables and other arbitrary values are intentionally rejected. * * @since 1.1.4 * * @param mixed $value Raw color value. * @param string $default_value Default fallback color. * @return string */ public static function sanitize_color( $value, $default_value = '#ffffff' ) { $value = trim( self::safe_unslash_scalar( $value ) ); $default_value = trim( self::safe_unslash_scalar( $default_value ) ); if ( '' === $default_value ) { $default_value = '#ffffff'; } $hex_color = sanitize_hex_color( $value ); if ( $hex_color ) { return $hex_color; } if ( self::is_valid_rgba_color( $value ) ) { return strtolower( preg_replace( '/\s+/', '', $value ) ); } $default_hex = sanitize_hex_color( $default_value ); if ( $default_hex ) { return $default_hex; } if ( self::is_valid_rgba_color( $default_value ) ) { return strtolower( preg_replace( '/\s+/', '', $default_value ) ); } return '#ffffff'; } /** * Determine whether a value is a strict rgba() color. * * @since 1.1.4 * * @param string $value Color value. * @return bool */ private static function is_valid_rgba_color( $value ) { if ( ! is_string( $value ) ) { return false; } // Regular expression to tightly bind allowed RGBA structures. $pattern = '/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+)\s*\)$/i'; if ( ! preg_match( $pattern, $value, $matches ) ) { return false; } $red = (int) $matches[1]; $green = (int) $matches[2]; $blue = (int) $matches[3]; $alpha = (float) $matches[4]; return ( $red >= 0 && $red <= 255 && $green >= 0 && $green <= 255 && $blue >= 0 && $blue <= 255 && $alpha >= 0 && $alpha <= 1 ); } /** * Sanitize multi-line textarea content. * * @since 1.1.4 * * @param mixed $value Raw textarea value. * @return string */ private static function sanitize_textarea_lines( $value ) { $value = self::safe_unslash_scalar( $value ); // Normalize line breaks prior to core sanitization. $value = str_replace( array( "\r\n", "\r" ), "\n", $value ); return sanitize_textarea_field( $value ); } /** * Sanitize custom CSS setting. * * Runtime inline CSS is being removed from the plugin. This keeps the * saved value text-only until the feature is reworked into a generated * external stylesheet or removed from the UI. * * @since 1.1.4 * * @param mixed $value Raw CSS value. * @return string */ private static function sanitize_custom_css( $value ) { return trim( wp_strip_all_tags( self::safe_unslash_scalar( $value ) ) ); } /* |-------------------------------------------------------------------------- | SECTION 5: Spinner HTML Allowlist |-------------------------------------------------------------------------- */ /** * Get the narrow allowed HTML schema for spinner markup. * * This should replace broad wp_kses_post() usage for spinner markup. * * @since 1.1.4 * * @return array */ public static function get_spinner_allowed_html() { // Strict allowlist for SVG manipulation to prevent XSS payloads. $allowed_html = array( 'div' => array( 'aria-hidden' => true, 'class' => true, 'role' => true, ), 'span' => array( 'aria-hidden' => true, 'class' => true, 'role' => true, ), 'svg' => array( 'aria-hidden' => true, 'class' => true, 'fill' => true, 'focusable' => true, 'height' => true, 'role' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, 'viewbox' => true, 'viewBox' => true, 'width' => true, 'xmlns' => true, ), 'circle' => array( 'class' => true, 'cx' => true, 'cy' => true, 'fill' => true, 'r' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, ), 'path' => array( 'class' => true, 'd' => true, 'fill' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, ), 'ellipse' => array( 'class' => true, 'cx' => true, 'cy' => true, 'fill' => true, 'rx' => true, 'ry' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, ), 'g' => array( 'aria-hidden' => true, 'class' => true, 'fill' => true, 'role' => true, 'stroke' => true, 'transform' => true, ), 'line' => array( 'class' => true, 'fill' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, 'x1' => true, 'x2' => true, 'y1' => true, 'y2' => true, ), 'polygon' => array( 'class' => true, 'fill' => true, 'points' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, ), 'polyline' => array( 'class' => true, 'fill' => true, 'points' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, ), 'rect' => array( 'class' => true, 'fill' => true, 'height' => true, 'rx' => true, 'ry' => true, 'stroke' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-width' => true, 'width' => true, 'x' => true, 'y' => true, ), ); /** * Filter allowed spinner HTML. * * Keep this intentionally narrow. It is used specifically for * spinner animation markup, not general post content. * * @since 1.1.4 * * @param array $allowed_html Allowed HTML schema. */ $allowed_html = apply_filters( 'aerospin_css_loading_spinners_spinner_allowed_html', $allowed_html ); $allowed_html = apply_filters( 'pure_css_spinners_spinner_allowed_html', $allowed_html ); return is_array( $allowed_html ) ? $allowed_html : array(); } /** * Sanitize spinner markup using the narrow spinner allowlist. * * @since 1.1.4 * * @param string $html Raw spinner HTML. * @return string */ public static function kses_spinner_html( $html ) { if ( ! is_string( $html ) || '' === $html ) { return ''; } // Pass markup through strict SVG specific KSES. return wp_kses( $html, self::get_spinner_allowed_html() ); } } } if ( ! class_exists( 'AeroSpin_CSS_Loading_Spinners_Helpers' ) ) { class_alias( 'ACLS_Helpers', 'AeroSpin_CSS_Loading_Spinners_Helpers' ); } if ( ! class_exists( 'Pure_CSS_Spinners_Helpers' ) ) { class_alias( 'ACLS_Helpers', 'Pure_CSS_Spinners_Helpers' ); } if ( ! class_exists( 'AreoSpin_Css_Loading_Spinners_Helpers' ) ) { class_alias( 'ACLS_Helpers', 'AreoSpin_Css_Loading_Spinners_Helpers' ); } /* |-------------------------------------------------------------------------- | SECTION 6: Procedural Standard Wrappers |-------------------------------------------------------------------------- | | These functions provide procedural access to AeroSpin CSS Loading Spinners helper methods, | adhering strictly to WordPress.org prefixing requirements. | */ if ( ! function_exists( 'aerospin_css_loading_spinners_get_settings_schema' ) ) { function aerospin_css_loading_spinners_get_settings_schema() { return ACLS_Helpers::get_settings_schema(); } } if ( ! function_exists( 'aerospin_css_loading_spinners_default_settings' ) ) { function aerospin_css_loading_spinners_default_settings() { return ACLS_Helpers::get_defaults(); } } if ( ! function_exists( 'aerospin_css_loading_spinners_get_default_settings' ) ) { function aerospin_css_loading_spinners_get_default_settings() { return ACLS_Helpers::get_defaults(); } } if ( ! function_exists( 'aerospin_css_loading_spinners_get_settings' ) ) { function aerospin_css_loading_spinners_get_settings() { return ACLS_Helpers::get_settings(); } } if ( ! function_exists( 'aerospin_css_loading_spinners_normalize_settings' ) ) { function aerospin_css_loading_spinners_normalize_settings( $settings ) { return ACLS_Helpers::normalize_settings( $settings ); } } if ( ! function_exists( 'aerospin_css_loading_spinners_sanitize_settings' ) ) { function aerospin_css_loading_spinners_sanitize_settings( $settings ) { return ACLS_Helpers::sanitize_settings( $settings ); } } if ( ! function_exists( 'aerospin_css_loading_spinners_clear_settings_cache' ) ) { function aerospin_css_loading_spinners_clear_settings_cache() { ACLS_Helpers::clear_cache(); } } if ( ! function_exists( 'aerospin_css_loading_spinners_sanitize_color' ) ) { function aerospin_css_loading_spinners_sanitize_color( $value, $default_value = '#ffffff' ) { return ACLS_Helpers::sanitize_color( $value, $default_value ); } } if ( ! function_exists( 'aerospin_css_loading_spinners_sanitize_spinner_key' ) ) { function aerospin_css_loading_spinners_sanitize_spinner_key( $value, $default_value = 'ring' ) { return ACLS_Helpers::sanitize_spinner_key( $value, $default_value ); } } if ( ! function_exists( 'aerospin_css_loading_spinners_get_spinner_allowed_html' ) ) { function aerospin_css_loading_spinners_get_spinner_allowed_html() { return ACLS_Helpers::get_spinner_allowed_html(); } } if ( ! function_exists( 'aerospin_css_loading_spinners_kses_spinner_html' ) ) { function aerospin_css_loading_spinners_kses_spinner_html( $html ) { return ACLS_Helpers::kses_spinner_html( $html ); } } // Backward-compatibility wrappers for legacy pure_css_spinners_* functions if ( ! function_exists( 'pure_css_spinners_get_settings_schema' ) ) { function pure_css_spinners_get_settings_schema() { return aerospin_css_loading_spinners_get_settings_schema(); } } if ( ! function_exists( 'pure_css_spinners_default_settings' ) ) { function pure_css_spinners_default_settings() { return aerospin_css_loading_spinners_default_settings(); } } if ( ! function_exists( 'pure_css_spinners_get_default_settings' ) ) { function pure_css_spinners_get_default_settings() { return aerospin_css_loading_spinners_get_default_settings(); } } if ( ! function_exists( 'pure_css_spinners_get_settings' ) ) { function pure_css_spinners_get_settings() { return aerospin_css_loading_spinners_get_settings(); } } if ( ! function_exists( 'pure_css_spinners_normalize_settings' ) ) { function pure_css_spinners_normalize_settings( $settings ) { return aerospin_css_loading_spinners_normalize_settings( $settings ); } } if ( ! function_exists( 'pure_css_spinners_sanitize_settings' ) ) { function pure_css_spinners_sanitize_settings( $settings ) { return aerospin_css_loading_spinners_sanitize_settings( $settings ); } } if ( ! function_exists( 'pure_css_spinners_clear_settings_cache' ) ) { function pure_css_spinners_clear_settings_cache() { aerospin_css_loading_spinners_clear_settings_cache(); } } if ( ! function_exists( 'pure_css_spinners_sanitize_color' ) ) { function pure_css_spinners_sanitize_color( $value, $default_value = '#ffffff' ) { return aerospin_css_loading_spinners_sanitize_color( $value, $default_value ); } } if ( ! function_exists( 'pure_css_spinners_sanitize_spinner_key' ) ) { function pure_css_spinners_sanitize_spinner_key( $value, $default_value = 'ring' ) { return aerospin_css_loading_spinners_sanitize_spinner_key( $value, $default_value ); } } if ( ! function_exists( 'pure_css_spinners_get_spinner_allowed_html' ) ) { function pure_css_spinners_get_spinner_allowed_html() { return aerospin_css_loading_spinners_get_spinner_allowed_html(); } } if ( ! function_exists( 'pure_css_spinners_kses_spinner_html' ) ) { function pure_css_spinners_kses_spinner_html( $html ) { return aerospin_css_loading_spinners_kses_spinner_html( $html ); } }