name; } /** * Safely get a value from an array by key. * * @param array $array * @param string $key * @param mixed $default * @return mixed */ public static function isset($array, $key, $default = false) { return $array[$key] ?? $default; } /** * Safely get a nested value from a two-level array. * * @param array $array * @param string $key1 * @param string $key2 * @param mixed $default * @return mixed */ public static function isset2($array, $key1, $key2, $default = false) { return $array[$key1][$key2] ?? $default; } /** * Convert a hex color string to an RGB array. * * @param string $hex Hex color (with or without #) * @param float|false $alpha Optional alpha value * @return array{r: int, g: int, b: int, a?: float} */ public static function hexToRGB($hex, $alpha = false) { $hex = str_replace('#', '', $hex); $length = strlen($hex); $rgb = [ 'r' => hexdec($length === 6 ? substr($hex, 0, 2) : ($length === 3 ? str_repeat(substr($hex, 0, 1), 2) : '0')), 'g' => hexdec($length === 6 ? substr($hex, 2, 2) : ($length === 3 ? str_repeat(substr($hex, 1, 1), 2) : '0')), 'b' => hexdec($length === 6 ? substr($hex, 4, 2) : ($length === 3 ? str_repeat(substr($hex, 2, 1), 2) : '0')), ]; if ($alpha !== false) { $rgb['a'] = $alpha; } return $rgb; } /** * Get the WooCommerce product gallery CSS selector for a given theme. * * @param string $theme Theme name * @return string CSS selector */ public static function getCustomSelector(string $theme): string { $theme = str_replace(' Child', '', $theme); $selectors = [ 'Woostify' => '.product-gallery', ]; return $selectors[$theme] ?? '.woocommerce-product-gallery'; } /** * Convert a theme name to a CSS-safe class string. * * @param string|null $string Theme name (defaults to current theme) * @return string Lowercase, underscored class name */ public static function getThemeClass($string = null) { if ($string === null) { $string = wp_get_theme()->name; } return strtolower(str_replace(' ', '_', $string)); } /** * Get a list of themes known to be incompatible with the plugin. * * @return array */ public static function getNotCompatibleThemes(): array { $settings = get_option('_bp3d_settings_'); $is_not_compatible = $settings['is_not_compatible'] ?? false; $themes = [ 'Twenty Twenty-Four', 'Twenty Twenty Three', 'Woostify', 'Raft', 'eStore', 'Customify', 'B Technologies', ]; if ($is_not_compatible) { return wp_parse_args([wp_get_theme()->name], $themes); } return $themes; } /** * Check if the current theme is compatible with the plugin. */ public static function isCompatibleTheme(): bool { if ( in_array(wp_get_theme()->name, self::getNotCompatibleThemes(), true) || (function_exists('wp_is_block_theme') && wp_is_block_theme()) ) { return false; } return true; } /** * Get a callable accessor for post meta values. * * Returns a closure that provides convenient access to meta fields * with support for default values, boolean casting, and nested keys. * * @param int $id Post ID * @param string $key Meta key * @return \Closure(string, mixed=, bool=, string|null=): mixed */ public static function getPostMeta($id, $key) { $meta = get_post_meta($id, $key, true); return self::return_function($meta); } /** * Create a closure accessor for an associative array. * * @param mixed $meta The data array (or other value) * @return \Closure(string, mixed=, bool=, string|null=): mixed */ public static function return_function($meta) { return function ($key, $default = null, $is_boolean = false, $key2 = null) use ($meta) { if ($key === 'all') { return $meta; } $value = $key2 ? ($meta[$key][$key2] ?? $default) : ($meta[$key] ?? $default); if ($is_boolean) { return $value == '1'; } return $value; }; } /** * Get a callable accessor for a plugin option. * * @param string $key Option key * @param mixed|null $default Default value * @return \Closure */ public static function getSettings($key, $default = null) { $settings = get_option($key, $default); return self::return_function($settings); } /** * remove pro attributes * * @param array $attributes * @return void */ public static function removeProAttributes(array $attributes): array { if (function_exists('bp3d_fs') && bp3d_fs()->can_use_premium_code()) { return $attributes; } $pro_keys = [ 'multiple', 'models', 'shadow', 'autoRotate', 'variant', 'rotateAlongX', 'rotateAlongY', 'exposure', 'environmentImage', 'useEnvironmentAsSkybox', 'zoomLevel', 'appliedTextures', 'toneMapping', 'hotspots', 'animation', 'selectedAnimation', 'hotspotStyle', 'lockXAxisRotation', 'lockYAxisRotation' ]; foreach ($pro_keys as $key) { unset($attributes[$key]); } if (isset($attributes['model']) && is_array($attributes['model'])) { $model_pro_keys = [ 'skyboxImage', 'environmentImage', 'arEnabled', 'arPlacement', 'arMode', 'arScale' ]; foreach ($model_pro_keys as $key) { unset($attributes['model'][$key]); } } unset($attributes['loading']); return $attributes; } }