<?php

/**
 * Plugin Name: The Studio Player
 * Plugin URI: https://studioplayer.de
 * Description: Showcase your mixes and masters with <strong>sample-accurate switching</strong> between two variants (A/B audio comparison). Our audio engine supports <strong>multichannel lossless FLAC streaming at 44.1kHz / 16-bit</strong>. Easily encode and upload your tracks, then compose playlists with metadata directly from our admin interface. Player integration with template design system for professional studio workflows. The Pro version adds 2 more slots (A/B/C/D), <strong>48kHz / 24-bit</strong> support, <strong>waveform JSON generation</strong> and advanced workflow tools.
 * Version: 0.9.69
 * Author: Peter Rahe
 * Author URI: https://studioplayer.de/donate
 * Requires at least: 6.0
 * Requires PHP: 7.4
 * Text Domain: the-studio-player
 * Domain Path: /languages
 * License: GPLv2 or later
 *
 *
 * @package The Studio Player
 */
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
if ( !function_exists( 'thespl_fs' ) ) {
    /**
     * Get the Freemius SDK instance for The Studio Player.
     *
     * @return Freemius SDK instance.
     */
    function thespl_fs() {
        global $thespl_fs;
        if ( !isset( $thespl_fs ) ) {
            // Include Freemius SDK.
            require_once __DIR__ . '/vendor/freemius/start.php';
            $thespl_fs = fs_dynamic_init( array(
                'id'                  => '22822',
                'slug'                => 'the-studio-player',
                'premium_slug'        => 'the-studio-player-pro',
                'type'                => 'plugin',
                'public_key'          => 'pk_e6c744075d86e65edcc95b026d51f',
                'is_premium'          => false,
                'premium_suffix'      => 'Pro',
                'has_addons'          => false,
                'has_paid_plans'      => true,
                'is_org_compliant'    => true,
                'trial'               => array(
                    'days'               => 7,
                    'is_require_payment' => false,
                ),
                'parallel_activation' => array(
                    'enabled'                  => true,
                    'premium_version_basename' => 'the-studio-player-pro/the-studio-player.php',
                ),
                'menu'                => array(
                    'slug'       => 'the-studio-player',
                    'first-path' => 'admin.php?page=the-studio-player',
                    'contact'    => false,
                ),
                'is_live'             => true,
            ) );
        }
        return $thespl_fs;
    }

    // Init Freemius.
    thespl_fs();
    // Signal that SDK was initiated.
    do_action( 'thespl_fs_loaded' );
}
$thespl_current_basename = basename( __DIR__ ) . '/' . basename( __FILE__ );
$thespl_current_is_pro = 'the-studio-player-pro/the-studio-player.php' === $thespl_current_basename;
$thespl_is_sandbox = defined( 'WP_SANDBOX_SCRAPING' ) && WP_SANDBOX_SCRAPING;
$thespl_free_basename = 'the-studio-player/the-studio-player.php';
$thespl_pro_basename = 'the-studio-player-pro/the-studio-player.php';
$thespl_plugin_dir = plugin_dir_path( __FILE__ );
$thespl_plugin_url = plugin_dir_url( __FILE__ );
$thespl_main_file = __FILE__;
$thespl_abort_bootstrap = false;
$thespl_overrides_file = __DIR__ . '/includes/bootstrap/thespl-bootstrap-overrides.php';
if ( file_exists( $thespl_overrides_file ) ) {
    require_once $thespl_overrides_file;
}
if ( $thespl_abort_bootstrap ) {
    return;
}
if ( $thespl_is_sandbox && function_exists( 'register_activation_hook' ) ) {
    if ( !$thespl_current_is_pro ) {
        /**
         * Resolve the activation conflict for the Free build.
         *
         * Stops activation when the Premium plugin is already active.
         *
         * @param string $pro_basename Premium plugin basename.
         * @return void
         */
        function thespl_handle_free_activation_conflict(  $pro_basename  ) {
            $active_plugins = (array) get_option( 'active_plugins', array() );
            $is_pro_active = in_array( $pro_basename, $active_plugins, true );
            if ( !$is_pro_active && function_exists( 'is_multisite' ) && is_multisite() ) {
                $network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
                $is_pro_active = is_array( $network_active_plugins ) && isset( $network_active_plugins[$pro_basename] );
            }
            if ( $is_pro_active ) {
                if ( !function_exists( 'deactivate_plugins' ) ) {
                    require_once ABSPATH . 'wp-admin/includes/plugin.php';
                }
                if ( function_exists( 'deactivate_plugins' ) ) {
                    deactivate_plugins( plugin_basename( __FILE__ ) );
                }
                wp_die( esc_html__( 'The Studio Player Free could not be activated because The Studio Player Pro is already active. Please keep Pro active, or deactivate Pro first if you want to use Free.', 'the-studio-player' ), esc_html__( 'Activation blocked', 'the-studio-player' ), array(
                    'back_link' => true,
                ) );
            }
            update_option( 'thespl_deferred_activation_setup', '1' );
        }

        register_activation_hook( __FILE__, static function () use($thespl_pro_basename) {
            thespl_handle_free_activation_conflict( $thespl_pro_basename );
        } );
        $thespl_active_plugins = (array) get_option( 'active_plugins', array() );
        $thespl_has_conflict = in_array( $thespl_pro_basename, $thespl_active_plugins, true );
        if ( !$thespl_has_conflict && function_exists( 'is_multisite' ) && is_multisite() ) {
            $thespl_network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
            $thespl_has_conflict = is_array( $thespl_network_active_plugins ) && isset( $thespl_network_active_plugins[$thespl_pro_basename] );
        }
        if ( $thespl_has_conflict ) {
            return;
        }
    }
}
thespl_fs()->set_basename( $thespl_current_is_pro, __FILE__ );
thespl_fs()->add_filter( 'default_currency', function ( $currency ) {
    unset($currency);
    return 'eur';
} );
thespl_fs()->add_filter( 'pricing/show_annual_in_monthly', '__return_false' );
/*
 * Enforce deterministic sibling activation policy:
 * - Free activation must never deactivate Pro.
 * - Pro activation may deactivate Free.
 */
thespl_fs()->add_filter(
    'is_submenu_visible',
    function ( $is_visible, $id ) {
        if ( in_array( $id, array(
            'account',
            'pricing',
            'contact',
            'support',
            'affiliation'
        ), true ) ) {
            return false;
        }
        return $is_visible;
    },
    10,
    2
);
thespl_fs()->add_action( 'after_uninstall', 'thespl_fs_uninstall_cleanup' );
if ( !function_exists( 'thespl_get_marketing_website_url' ) ) {
    /**
     * Get the product website URL used for admin links.
     *
     * @return string
     */
    function thespl_get_marketing_website_url() {
        return 'https://studioplayer.de/';
    }

}
if ( !function_exists( 'thespl_get_marketing_pricing_url' ) ) {
    /**
     * Get the pricing URL used for upgrade calls to action.
     *
     * @return string
     */
    function thespl_get_marketing_pricing_url() {
        return thespl_get_marketing_website_url() . '#pricing';
    }

}
if ( !function_exists( 'thespl_get_customer_portal_url' ) ) {
    /**
     * Get the external Freemius customer portal URL.
     *
     * @return string
     */
    function thespl_get_customer_portal_url() {
        return 'https://customers.freemius.com/';
    }

}
if ( !function_exists( 'thespl_get_freemius_account_url' ) ) {
    /**
     * Get the preferred Freemius account management URL.
     *
     * @return string
     */
    function thespl_get_freemius_account_url() {
        return (string) apply_filters( 'thespl_freemius_account_url', thespl_get_customer_portal_url() );
    }

}
if ( !function_exists( 'thespl_get_support_url' ) ) {
    /**
     * Get the public support URL.
     *
     * @return string
     */
    function thespl_get_support_url() {
        return 'https://studioplayer.de/support/';
    }

}
if ( !function_exists( 'thespl_get_min_capability' ) ) {
    /**
     * Get minimum capability required for plugin access areas.
     *
     * @return string
     */
    function thespl_get_min_capability() {
        $settings = thespl_get_player_settings();
        $allowed = array('manage_options', 'edit_others_posts', 'publish_posts');
        $cap = ( !empty( $settings['min_capability'] ) ? $settings['min_capability'] : 'edit_others_posts' );
        if ( !is_string( $cap ) || !in_array( $cap, $allowed, true ) ) {
            $cap = 'edit_others_posts';
        }
        return apply_filters( 'thespl_min_capability', $cap );
    }

}
// Define Constants.
if ( !defined( 'THESPL_PLUGIN_DIR' ) ) {
    define( 'THESPL_PLUGIN_DIR', $thespl_plugin_dir );
}
if ( !defined( 'THESPL_PLUGIN_URL' ) ) {
    define( 'THESPL_PLUGIN_URL', $thespl_plugin_url );
}
if ( !defined( 'THESPL_VERSION' ) ) {
    define( 'THESPL_VERSION', '0.9.69' );
}
if ( !defined( 'THESPL_CODENAME' ) ) {
    define( 'THESPL_CODENAME', 'dev' );
}
if ( !defined( 'THESPL_SAMPLE_CHUNK_BYTES' ) ) {
    define( 'THESPL_SAMPLE_CHUNK_BYTES', 2097152 );
}
if ( !defined( 'THESPL_BUILD_TYPE' ) ) {
    define( 'THESPL_BUILD_TYPE', 'free' );
}
if ( !defined( 'THESPL_HAS_PRO_ASSETS' ) ) {
    define( 'THESPL_HAS_PRO_ASSETS', false );
}
if ( !function_exists( 'thespl_get_build_type' ) ) {
    /**
     * Get the current plugin build type.
     *
     * @return string
     */
    function thespl_get_build_type() {
        return ( 'pro' === THESPL_BUILD_TYPE ? 'pro' : 'free' );
    }

}
if ( !function_exists( 'thespl_has_pro_assets' ) ) {
    /**
     * Determine whether Pro assets are active in the current build.
     *
     * @return bool
     */
    function thespl_has_pro_assets() {
        return (bool) THESPL_HAS_PRO_ASSETS;
    }

}
if ( !function_exists( 'thespl_get_player_settings' ) ) {
    /**
     * Get plugin settings with defaults.
     *
     * @return array
     */
    function thespl_get_player_settings() {
        $defaults = array(
            'debug_console_enabled'                 => 0,
            'onboarding_enabled'                    => 1,
            'streaming_auto_detect_network'         => 1,
            'streaming_chunk_level'                 => 4,
            'streaming_prebuffer_sec'               => 0,
            'streaming_continue_buffer_on_pause'    => 1,
            'streaming_prefetch_next_on_ahead'      => 1,
            'streaming_ready_ahead_sec'             => 1,
            'fade_switch_duration_ms'               => 1,
            'streaming_security_enabled'            => 1,
            'streaming_htaccess_enabled'            => 1,
            'streaming_token_lifetime'              => 60,
            'streaming_rate_limit_enabled'          => 1,
            'streaming_rate_limit_rpm'              => 300,
            'streaming_rate_limit_burst'            => 80,
            'show_security_verification'            => 1,
            'min_capability'                        => 'edit_others_posts',
            'remote_global_warning_banners_enabled' => 0,
        );
        $settings = get_option( 'thespl_player_settings', array() );
        return wp_parse_args( (array) $settings, $defaults );
    }

}
if ( !function_exists( 'thespl_get_muxer_settings' ) ) {
    /**
     * Get muxer settings with defaults.
     *
     * @return array
     */
    function thespl_get_muxer_settings() {
        $max_upload = wp_max_upload_size();
        $default_chunk = 524288;
        if ( thespl_is_pro_active() ) {
            if ( $max_upload > 20971520 ) {
                $default_chunk = 2097152;
            }
            if ( $max_upload > 67108864 ) {
                $default_chunk = 5242880;
            }
        }
        $saved = get_option( 'thespl_muxer_settings', array() );
        $subdir = '';
        if ( isset( $saved['subdir'] ) && '' !== trim( (string) $saved['subdir'] ) ) {
            $subdir = (string) $saved['subdir'];
        }
        $chunk_size = ( isset( $saved['chunk_size'] ) ? (int) $saved['chunk_size'] : (int) $default_chunk );
        $allowed = array(
            262144,
            524288,
            1048576,
            2097152,
            5242880
        );
        $limit = (int) $max_upload;
        if ( $limit > 0 ) {
            $effective = array();
            foreach ( $allowed as $size ) {
                if ( $size <= $limit ) {
                    $effective[] = $size;
                }
            }
            if ( empty( $effective ) ) {
                $effective = array(262144);
            }
            if ( !in_array( $chunk_size, $effective, true ) ) {
                $chunk_size = max( $effective );
            }
        }
        return array(
            'subdir'     => $subdir,
            'chunk_size' => $chunk_size,
        );
    }

}
if ( !function_exists( 'thespl_is_pro_active' ) ) {
    /**
     * Determine whether the Pro components are available.
     *
     * @return bool
     */
    function thespl_is_pro_active() {
        return thespl_has_pro_assets();
    }

}
if ( !function_exists( 'thespl_can_use_premium_code' ) ) {
    /**
     * Determine whether premium code can be used.
     *
     * @return bool
     */
    function thespl_can_use_premium_code() {
        return false;
    }

}
if ( !function_exists( 'thespl_get_capability_profile' ) ) {
    /**
     * Get the current capability profile for Free/Pro features.
     *
     * @return array
     */
    function thespl_get_capability_profile() {
        $has_pro_assets = thespl_has_pro_assets();
        $muxer_engine = ( function_exists( 'thespl_get_muxer_engine' ) ? thespl_get_muxer_engine() : null );
        $profile = array(
            'is_pro'                 => $has_pro_assets,
            'supports_muxer_slots_4' => $muxer_engine && method_exists( $muxer_engine, 'get_operational_slot_count' ) && $muxer_engine->get_operational_slot_count() > 2,
            'supports_data_recovery' => $has_pro_assets,
            'supports_hi_res_muxer'  => $muxer_engine && method_exists( $muxer_engine, 'supports_high_resolution_input' ) && $muxer_engine->supports_high_resolution_input(),
        );
        return $profile;
    }

}
if ( !function_exists( 'thespl_get_component_status' ) ) {
    /**
     * Get the current component availability status.
     *
     * @return array
     */
    function thespl_get_component_status() {
        $profile = thespl_get_capability_profile();
        return array(
            'has_pro_components' => !empty( $profile['is_pro'] ),
        );
    }

}
if ( !function_exists( 'thespl_get_license_profile' ) ) {
    /**
     * Get the normalized license profile for The Studio Player.
     *
     * Provides a single source of truth for license type, plan kind and high-level
     * support status for the current build.
     *
     * @return array {
     *     License profile data.
     *
     *     @type string   $code_access      'free' or 'premium'.
     *     @type string   $plan_kind        'free', 'pro_recurring', 'pro_recurring_issue', 'pro_lifetime', 'pro_lifetime_issue', or 'unknown'.
     *     @type string   $status           'free', 'pro_active', 'pro_issue', or 'unknown'.
     *     @type bool     $has_premium      Whether any premium access is associated.
     *     @type bool     $account_issue    Whether an account or license issue is detected.
     *     @type string   $support_state    'active', 'expired', or 'unknown'.
     *     @type int|null $support_until_ts Support end timestamp if known, otherwise null.
     *     @type bool     $is_offline       True when Freemius is not available.
     *     @type array    $raw              Raw helper data such as plan name and title.
     * }
     */
    function thespl_get_license_profile() {
        static $profile = null;
        if ( null !== $profile ) {
            return $profile;
        }
        $profile = array(
            'code_access'      => 'free',
            'plan_kind'        => 'free',
            'status'           => 'free',
            'has_premium'      => false,
            'account_issue'    => false,
            'support_state'    => 'unknown',
            'support_until_ts' => null,
            'is_intro_offer'   => false,
            'intro_ends'       => '',
            'intro_ends_ts'    => null,
            'intro_days_left'  => null,
            'is_offline'       => false,
            'raw'              => array(),
        );
        return ( is_array( $profile ) ? $profile : array() );
    }

}
if ( !function_exists( 'thespl_get_license_status' ) ) {
    /**
     * Get the current license status snapshot.
     *
     * @return array
     */
    function thespl_get_license_status() {
        $profile = ( function_exists( 'thespl_get_license_profile' ) ? thespl_get_license_profile() : array() );
        $status = array(
            'status'        => 'free',
            'plan'          => 'free',
            'expiry'        => '',
            'has_premium'   => false,
            'is_paying'     => false,
            'is_offline'    => false,
            'account_issue' => false,
            'is_intro'      => false,
            'intro_ends'    => '',
            'intro_days'    => null,
        );
        if ( !empty( $profile ) && is_array( $profile ) ) {
            $status['status'] = ( isset( $profile['status'] ) ? (string) $profile['status'] : 'free' );
            $status['has_premium'] = ( isset( $profile['has_premium'] ) ? (bool) $profile['has_premium'] : false );
            $status['is_offline'] = ( isset( $profile['is_offline'] ) ? (bool) $profile['is_offline'] : false );
            $status['account_issue'] = ( isset( $profile['account_issue'] ) ? (bool) $profile['account_issue'] : false );
            $status['is_intro'] = ( isset( $profile['is_intro_offer'] ) ? (bool) $profile['is_intro_offer'] : false );
            $status['intro_ends'] = ( isset( $profile['intro_ends'] ) ? (string) $profile['intro_ends'] : '' );
            $status['intro_days'] = ( isset( $profile['intro_days_left'] ) && is_numeric( $profile['intro_days_left'] ) ? (int) $profile['intro_days_left'] : null );
            if ( isset( $profile['raw'] ) && is_array( $profile['raw'] ) && isset( $profile['raw']['is_paying'] ) ) {
                $status['is_paying'] = (bool) $profile['raw']['is_paying'];
            }
            if ( 'free' !== $status['status'] ) {
                $status['plan'] = 'pro';
            }
            if ( $status['is_intro'] && '' !== $status['intro_ends'] ) {
                $status['expiry'] = $status['intro_ends'];
            }
        }
        return ( is_array( $status ) ? $status : array() );
    }

}
if ( !function_exists( 'thespl_get_muxer_license_profile' ) ) {
    /**
     * Get the muxer-oriented license profile.
     *
     * @return array
     */
    function thespl_get_muxer_license_profile() {
        return array(
            'build_type'    => 'free',
            'license_mode'  => 'FREE',
            'license_label' => __( 'Free', 'the-studio-player' ),
        );
    }

}
if ( !function_exists( 'thespl_filter_upload_mimes' ) ) {
    /**
     * Extend allowed upload MIME types for FLAC and JSON files.
     *
     * @param array      $mimes List of existing MIME types keyed by extension.
     * @param int|object $user  User ID or object (unused).
     * @return array Filtered list of MIME types.
     */
    function thespl_filter_upload_mimes(  $mimes, $user = null  ) {
        if ( !is_array( $mimes ) ) {
            $mimes = array();
        }
        if ( null !== $user ) {
            unset($user);
        }
        if ( !isset( $mimes['flac'] ) || '' === $mimes['flac'] ) {
            $mimes['flac'] = 'audio/flac';
        }
        if ( !isset( $mimes['json'] ) || '' === $mimes['json'] ) {
            $mimes['json'] = 'application/json';
        }
        return $mimes;
    }

}
add_filter(
    'upload_mimes',
    'thespl_filter_upload_mimes',
    999,
    2
);
if ( !function_exists( 'thespl_get_upload_mime_types' ) ) {
    /**
     * Get MIME types used for THESPL uploads (FLAC and JSON aware).
     *
     * @return array MIME types keyed by extension.
     */
    function thespl_get_upload_mime_types() {
        $mimes = wp_get_mime_types();
        if ( !is_array( $mimes ) ) {
            $mimes = array();
        }
        if ( !isset( $mimes['flac'] ) || '' === $mimes['flac'] ) {
            $mimes['flac'] = 'audio/flac';
        }
        if ( !isset( $mimes['json'] ) || '' === $mimes['json'] ) {
            $mimes['json'] = 'application/json';
        }
        return $mimes;
    }

}
require_once $thespl_plugin_dir . 'includes/variants/class-thespl-variant-engine.php';
require_once $thespl_plugin_dir . 'includes/variants/thespl-variant-engine.php';
require_once $thespl_plugin_dir . 'includes/muxer/class-thespl-muxer-engine.php';
require_once $thespl_plugin_dir . 'includes/muxer/thespl-muxer-engine.php';
// Include Admin Logic.
if ( is_admin() ) {
    require_once $thespl_plugin_dir . 'includes/admin/admin-loader.php';
}
require_once $thespl_plugin_dir . 'includes/thespl-template-registry.php';
require_once $thespl_plugin_dir . 'includes/thespl-design.php';
require_once $thespl_plugin_dir . 'includes/thespl-streaming.php';
require_once $thespl_plugin_dir . 'includes/thespl-frontend.php';
require_once $thespl_plugin_dir . 'includes/thespl-color-probe.php';
/**
 * Run activation setup shared by Free and Pro builds.
 *
 * Registers rewrite rules, initializes options and prepares upload directories.
 *
 * @return Closure
 */
$thespl_run_activation_setup = static function () {
    thespl_add_stream_rewrite_rules();
    flush_rewrite_rules();
    // Generate a secret key for streaming security if it doesn't exist.
    if ( !get_option( 'thespl_streaming_secret_key' ) ) {
        update_option( 'thespl_streaming_secret_key', wp_generate_password( 64, true, true ) );
    }
    // Initialize default settings if not set.
    $player_settings = get_option( 'thespl_player_settings' );
    if ( !$player_settings ) {
        update_option( 'thespl_player_settings', thespl_get_player_settings() );
    } elseif ( is_array( $player_settings ) && (isset( $player_settings['muxer_upload_subdir'] ) || isset( $player_settings['muxer_chunk_size'] )) ) {
        // Cleanup legacy keys from player settings if they exist (migration to thespl_muxer_settings).
        unset($player_settings['muxer_upload_subdir']);
        unset($player_settings['muxer_chunk_size']);
        update_option( 'thespl_player_settings', $player_settings );
    }
    $uploads = wp_upload_dir();
    if ( !empty( $uploads['basedir'] ) && is_string( $uploads['basedir'] ) ) {
        $root_dir = trailingslashit( $uploads['basedir'] ) . 'the-studio-player/';
        $audio_dir = trailingslashit( $root_dir . 'audio' );
        wp_mkdir_p( $root_dir );
        wp_mkdir_p( $audio_dir );
        $base_dir = trailingslashit( $root_dir . 'templates/player' );
        wp_mkdir_p( $base_dir );
    }
    if ( thespl_has_pro_assets() ) {
        update_option( 'thespl_fs_license_prompt_pending', '1' );
    }
    update_option( 'thespl_do_activation_redirect', '1' );
};
add_action( 'init', static function () use($thespl_run_activation_setup) {
    if ( '1' !== get_option( 'thespl_deferred_activation_setup', '' ) ) {
        return;
    }
    delete_option( 'thespl_deferred_activation_setup' );
    $thespl_run_activation_setup();
}, 999 );
add_action( 'admin_init', 'thespl_maybe_do_activation_redirect' );
if ( !function_exists( 'thespl_maybe_do_activation_redirect' ) ) {
    /**
     * Handle activation redirect to plugin dashboard.
     *
     * @return void
     */
    function thespl_maybe_do_activation_redirect() {
        if ( !is_admin() ) {
            return;
        }
        if ( is_network_admin() ) {
            return;
        }
        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
            return;
        }
        if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
            return;
        }
        $redirect_flag = get_option( 'thespl_do_activation_redirect', '' );
        if ( '1' !== (string) $redirect_flag ) {
            return;
        }
        delete_option( 'thespl_do_activation_redirect' );
        if ( !function_exists( 'thespl_current_user_can_policy' ) ) {
            return;
        }
        if ( !thespl_current_user_can_policy( 'plugin_access' ) ) {
            return;
        }
        $target_url = admin_url( 'admin.php?page=the-studio-player' );
        if ( '' === $target_url ) {
            return;
        }
        wp_safe_redirect( $target_url );
        exit;
    }

}
add_filter( 'allowed_redirect_hosts', 'thespl_register_support_redirect_host' );
if ( !function_exists( 'thespl_register_support_redirect_host' ) ) {
    /**
     * Register custom hosts allowed for support redirects.
     *
     * @param array $hosts Existing allowed redirect hosts.
     *
     * @return array Filtered allowed redirect hosts.
     */
    function thespl_register_support_redirect_host(  $hosts  ) {
        if ( !is_array( $hosts ) ) {
            $hosts = array();
        }
        $hosts[] = 'studioplayer.de';
        $hosts[] = 'www.studioplayer.de';
        $hosts[] = 'customers.freemius.com';
        return array_values( array_unique( $hosts ) );
    }

}
if ( !function_exists( 'thespl_fs_uninstall_cleanup' ) ) {
    /**
     * Cleanup plugin data after Freemius uninstall event.
     *
     * @return void
     */
    function thespl_fs_uninstall_cleanup() {
        $uninstall_remove_uploads_raw = get_option( 'thespl_uninstall_remove_uploads', '' );
        if ( !is_string( $uninstall_remove_uploads_raw ) ) {
            $uninstall_remove_uploads_raw = '';
        }
        $uninstall_remove_uploads = strtolower( trim( $uninstall_remove_uploads_raw ) );
        $remove_all_user_data = 'yes' === $uninstall_remove_uploads;
        if ( $remove_all_user_data ) {
            $playlists = get_posts( array(
                'post_type'      => 'thespl_playlist',
                'post_status'    => 'any',
                'posts_per_page' => -1,
                'fields'         => 'ids',
            ) );
            if ( !empty( $playlists ) ) {
                foreach ( $playlists as $post_id ) {
                    wp_delete_post( $post_id, true );
                }
            }
            $attachments = get_posts( array(
                'post_type'      => 'attachment',
                'post_status'    => 'inherit',
                'posts_per_page' => -1,
                'fields'         => 'ids',
                'meta_query'     => array(array(
                    'key'     => '_thespl_fingerprint',
                    'compare' => 'EXISTS',
                )),
                'no_found_rows'  => true,
            ) );
            if ( !empty( $attachments ) ) {
                foreach ( $attachments as $attachment_id ) {
                    wp_delete_attachment( (int) $attachment_id, true );
                }
            }
        }
        global $wpdb;
        // Uninstall-only bulk cleanup of plugin options and transients.
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk deletion of plugin-specific options during uninstall is more efficient via direct query.
        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", 'thespl_%' ) );
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk deletion of transients during uninstall is more efficient via direct query.
        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", '_transient_thespl_%' ) );
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk deletion of transient timeouts during uninstall is more efficient via direct query.
        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", '_transient_timeout_thespl_%' ) );
        if ( $remove_all_user_data ) {
            $uploads = wp_get_upload_dir();
            if ( !empty( $uploads['basedir'] ) && is_string( $uploads['basedir'] ) ) {
                $base_dir = trailingslashit( $uploads['basedir'] ) . 'the-studio-player';
                if ( is_dir( $base_dir ) ) {
                    require_once ABSPATH . 'wp-admin/includes/file.php';
                    if ( WP_Filesystem() ) {
                        global $wp_filesystem;
                        if ( $wp_filesystem->is_dir( $base_dir ) ) {
                            $wp_filesystem->delete( $base_dir, true, 'd' );
                        }
                    }
                }
            }
        }
        flush_rewrite_rules();
    }

}