| @@ -4,177 +4,251 @@ | ||
| 4 | 4 | |
| 5 | 5 | defined( 'ABSPATH' ) || exit; |
| 6 | 6 | |
| 7 | 7 | class Helper { |
| 8 | - const HOSTINGER_LOCALES = array( | |
| 9 | - 'lt_LT' => 'hostinger.lt', | |
| 10 | - 'uk_UA' => 'hostinger.com.ua', | |
| 11 | - 'id_ID' => 'hostinger.co.id', | |
| 12 | - 'en_US' => 'hostinger.com', | |
| 13 | - 'es_ES' => 'hostinger.es', | |
| 14 | - 'es_AR' => 'hostinger.com.ar', | |
| 15 | - 'es_MX' => 'hostinger.mx', | |
| 16 | - 'es_CO' => 'hostinger.co', | |
| 17 | - 'pt_BR' => 'hostinger.com.br', | |
| 18 | - 'ro_RO' => 'hostinger.ro', | |
| 19 | - 'fr_FR' => 'hostinger.fr', | |
| 20 | - 'it_IT' => 'hostinger.it', | |
| 21 | - 'pl_PL' => 'hostinger.pl', | |
| 22 | - 'en_PH' => 'hostinger.ph', | |
| 23 | - 'ar_AE' => 'hostinger.ae', | |
| 24 | - 'ms_MY' => 'hostinger.my', | |
| 25 | - 'ko_KR' => 'hostinger.kr', | |
| 26 | - 'vi_VN' => 'hostinger.vn', | |
| 27 | - 'th_TH' => 'hostinger.in.th', | |
| 28 | - 'tr_TR' => 'hostinger.web.tr', | |
| 29 | - 'pt_PT' => 'hostinger.pt', | |
| 30 | - 'de_DE' => 'hostinger.de', | |
| 31 | - 'en_IN' => 'hostinger.in', | |
| 32 | - 'ja_JP' => 'hostinger.jp', | |
| 33 | - 'nl_NL' => 'hostinger.nl', | |
| 34 | - 'en_GB' => 'hostinger.co.uk', | |
| 35 | - 'el_GR' => 'hostinger.gr', | |
| 36 | - 'cs_CZ' => 'hostinger.cz', | |
| 37 | - 'hu_HU' => 'hostinger.hu', | |
| 38 | - 'sv_SE' => 'hostinger.se', | |
| 39 | - 'da_DK' => 'hostinger.dk', | |
| 40 | - 'fi_FI' => 'hostinger.fi', | |
| 41 | - 'sk_SK' => 'hostinger.sk', | |
| 42 | - 'no_NO' => 'hostinger.no', | |
| 43 | - 'hr_HR' => 'hostinger.hr', | |
| 44 | - 'zh_HK' => 'hostinger.com.hk', | |
| 45 | - 'he_IL' => 'hostinger.co.il', | |
| 46 | - 'lv_LV' => 'hostinger.lv', | |
| 47 | - 'et_EE' => 'hostinger.ee', | |
| 48 | - 'ur_PK' => 'hostinger.pk', | |
| 49 | - ); | |
| 8 | + public const HOSTINGER_FREE_SUBDOMAIN_URL = 'hostingersite.com'; | |
| 9 | + public const HOSTINGER_PAGE = '/wp-admin/admin.php?page=hostinger'; | |
| 10 | + public const CLIENT_WOO_COMPLETED_ACTIONS = 'woocommerce_task_list_tracked_completed_tasks'; | |
| 11 | + private const PROMOTIONAL_LINKS = array( | |
| 12 | + 'fr_FR' => 'https://www.hostinger.fr/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 13 | + 'es_ES' => 'https://www.hostinger.es/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 14 | + 'ar' => 'https://www.hostinger.ae/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 15 | + 'zh_CN' => 'https://www.hostinger.com.hk/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 16 | + 'id_ID' => 'https://www.hostinger.co.id/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 17 | + 'lt_LT' => 'https://www.hostinger.lt/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 18 | + 'pt_PT' => 'https://www.hostinger.pt/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 19 | + 'uk' => 'https://www.hostinger.com.ua/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 20 | + 'tr_TR' => 'https://www.hostinger.com.tr/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 21 | + 'en_US' => 'https://www.hostinger.com/cpanel-login?r=%2Fjump-to%2Fnew-panel%2Fsection%2Freferrals&utm_source=Banner&utm_medium=HostingerWPplugin', | |
| 22 | + ); | |
| 50 | 23 | |
| 51 | - public const HOMEPAGE_DISPLAY = 'page'; | |
| 24 | + private const HPANEL_DOMAIN_URL = 'https://hpanel.hostinger.com/websites/'; | |
| 52 | 25 | |
| 53 | - /** | |
| 54 | - * | |
| 55 | - * Check if plugin is active | |
| 56 | - * | |
| 57 | - * @since 1.0.0 | |
| 58 | - * @access public | |
| 59 | - */ | |
| 60 | - public static function is_plugin_active( $plugin_slug ): bool { | |
| 61 | - $active_plugins = (array) get_option( 'active_plugins', array() ); | |
| 62 | - foreach ( $active_plugins as $active_plugin ) { | |
| 63 | - if ( strpos( $active_plugin, $plugin_slug . '.php' ) !== false ) { | |
| 64 | - return true; | |
| 65 | - } | |
| 66 | - } | |
| 26 | + /** | |
| 27 | + * | |
| 28 | + * Check if plugin is active | |
| 29 | + * | |
| 30 | + * @since 1.0.0 | |
| 31 | + * @access public | |
| 32 | + */ | |
| 33 | + public static function is_plugin_active( $plugin_slug ): bool { | |
| 34 | + $active_plugins = (array) get_option( 'active_plugins', array() ); | |
| 35 | + foreach ( $active_plugins as $active_plugin ) { | |
| 36 | + if ( strpos( $active_plugin, $plugin_slug . '.php' ) !== false ) { | |
| 37 | + return true; | |
| 38 | + } | |
| 39 | + } | |
| 67 | 40 | |
| 68 | - return false; | |
| 69 | - } | |
| 41 | + return false; | |
| 42 | + } | |
| 70 | 43 | |
| 71 | - public function is_preview_domain( $headers = null ): bool { | |
| 72 | - // @codeCoverageIgnoreStart | |
| 73 | - if ( $headers === null && function_exists( 'getallheaders' ) ) { | |
| 74 | - $headers = getallheaders(); | |
| 75 | - } | |
| 76 | - // @codeCoverageIgnoreEnd | |
| 77 | - if ( isset( $headers['X-Preview-Indicator'] ) && $headers['X-Preview-Indicator'] ) { | |
| 78 | - return true; | |
| 79 | - } | |
| 44 | + public static function get_api_token(): string { | |
| 45 | + $api_token = ''; | |
| 46 | + $token_file = HOSTINGER_WP_TOKEN; | |
| 80 | 47 | |
| 81 | - return false; | |
| 82 | - } | |
| 48 | + if ( file_exists( $token_file ) && ! empty( file_get_contents( $token_file ) ) ) { | |
| 49 | + $api_token = file_get_contents( $token_file ); | |
| 50 | + } | |
| 83 | 51 | |
| 84 | - public static function woocommerce_onboarding_choice(): bool { | |
| 85 | - return (bool) get_option( 'hostinger_woo_onboarding_choice', false ); | |
| 86 | - } | |
| 52 | + return $api_token; | |
| 53 | + } | |
| 87 | 54 | |
| 88 | - public static function generate_bypass_code( $length ) { | |
| 89 | - $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | |
| 90 | - $code = ''; | |
| 91 | - $max_index = strlen( $characters ) - 1; | |
| 55 | + /** | |
| 56 | + * | |
| 57 | + * Get the host info (domain, subdomain, subdirectory) | |
| 58 | + * | |
| 59 | + * @since 1.7.0 | |
| 60 | + * @access public | |
| 61 | + */ | |
| 62 | + public function get_host_info(): string { | |
| 63 | + $host = isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( $_SERVER['HTTP_HOST'] ) : ''; | |
| 64 | + $site_url = get_site_url(); | |
| 65 | + $site_url = preg_replace( '#^https?://#', '', $site_url ); | |
| 92 | 66 | |
| 93 | - for ( $i = 0; $i < $length; $i++ ) { | |
| 94 | - $random_index = wp_rand( 0, $max_index ); | |
| 95 | - $code .= $characters[ $random_index ]; | |
| 96 | - } | |
| 67 | + if ( ! empty( $site_url ) && ! empty( $host ) && strpos( $site_url, $host ) === 0 ) { | |
| 68 | + if ( $site_url === $host ) { | |
| 69 | + return $host; | |
| 70 | + } else { | |
| 71 | + return substr( $site_url, strlen( $host ) + 1 ); | |
| 72 | + } | |
| 73 | + } | |
| 97 | 74 | |
| 98 | - return $code; | |
| 99 | - } | |
| 75 | + return $host; | |
| 76 | + } | |
| 100 | 77 | |
| 78 | + public function is_preview_domain(): bool { | |
| 79 | + if ( function_exists( 'getallheaders' ) ) { | |
| 80 | + $headers = getallheaders(); | |
| 81 | + } | |
| 101 | 82 | |
| 83 | + if ( isset( $headers['X-Preview-Indicator'] ) && $headers['X-Preview-Indicator'] ) { | |
| 84 | + return true; | |
| 85 | + } | |
| 102 | 86 | |
| 103 | - public function get_hostinger_plugin_url(): string { | |
| 104 | - $website_locale = get_locale() ?? 'en_US'; | |
| 105 | - $reseller_locale = get_option( 'hostinger_reseller', null ); | |
| 106 | - $base_domain = $reseller_locale ?? ( self::HOSTINGER_LOCALES[ $website_locale ] ?? 'hostinger.com' ); | |
| 87 | + return false; | |
| 88 | + } | |
| 107 | 89 | |
| 108 | - $plugin_url = rtrim( $base_domain, '/' ) . '/'; | |
| 109 | - $plugin_url .= str_replace( ABSPATH, '', HOSTINGER_ABSPATH ); | |
| 90 | + public function is_free_subdomain(): bool { | |
| 91 | + $site_url = preg_replace( '#^https?://#', '', get_site_url() ); | |
| 110 | 92 | |
| 111 | - return $plugin_url; | |
| 112 | - } | |
| 93 | + return ! empty( $site_url ) && strpos( $site_url, self::HOSTINGER_FREE_SUBDOMAIN_URL ) !== false; | |
| 94 | + } | |
| 113 | 95 | |
| 114 | - public function get_recommended_php_version(): string { | |
| 115 | - $wp_version = get_bloginfo( 'version' ); | |
| 96 | + public function is_hostinger_admin_page(): bool { | |
| 116 | 97 | |
| 117 | - if ( empty( $wp_version ) ) { | |
| 118 | - return '8.2'; | |
| 119 | - } | |
| 98 | + if ( ! isset( $_SERVER['REQUEST_URI'] ) ) { | |
| 99 | + return false; | |
| 100 | + } | |
| 120 | 101 | |
| 121 | - // Remove any additional version info (like -RC1, -beta1, etc.). | |
| 122 | - $wp_version = preg_replace( '/[-+].*$/', '', $wp_version ); | |
| 102 | + $current_uri = sanitize_text_field( $_SERVER['REQUEST_URI'] ); | |
| 123 | 103 | |
| 124 | - if ( version_compare( $wp_version, '6.6', '>=' ) ) { | |
| 125 | - return '8.2'; | |
| 126 | - } | |
| 104 | + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { | |
| 105 | + return false; | |
| 106 | + } | |
| 127 | 107 | |
| 128 | - if ( version_compare( $wp_version, '6.3', '>=' ) ) { | |
| 129 | - return '8.1'; | |
| 130 | - } | |
| 108 | + if ( isset( $current_uri ) && strpos( $current_uri, '/wp-json/' ) !== false ) { | |
| 109 | + return false; | |
| 110 | + } | |
| 131 | 111 | |
| 132 | - if ( version_compare( $wp_version, '5.3', '>=' ) ) { | |
| 133 | - return '7.4'; | |
| 134 | - } | |
| 112 | + if ( strpos( $current_uri, self::HOSTINGER_PAGE ) !== false ) { | |
| 113 | + return true; | |
| 114 | + } | |
| 135 | 115 | |
| 136 | - if ( version_compare( $wp_version, '5.0', '>=' ) ) { | |
| 137 | - return '7.3'; | |
| 138 | - } | |
| 116 | + return false; | |
| 117 | + } | |
| 139 | 118 | |
| 140 | - if ( version_compare( $wp_version, '4.9', '=' ) ) { | |
| 141 | - return '7.2'; | |
| 142 | - } | |
| 119 | + /** | |
| 120 | + * | |
| 121 | + * Error log | |
| 122 | + * | |
| 123 | + * @since 1.9.6 | |
| 124 | + * @access public | |
| 125 | + */ | |
| 126 | + public function error_log( string $message ): void { | |
| 127 | + if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) { | |
| 128 | + error_log( print_r( $message, true ) ); | |
| 129 | + } | |
| 130 | + } | |
| 143 | 131 | |
| 144 | - if ( version_compare( $wp_version, '4.7', '>=' ) ) { | |
| 145 | - return '7.1'; | |
| 146 | - } | |
| 132 | + public function default_woocommerce_survey_steps_completed( array $steps ): bool { | |
| 133 | + $completed_actions = get_option( self::CLIENT_WOO_COMPLETED_ACTIONS, array() ); | |
| 147 | 134 | |
| 148 | - if ( version_compare( $wp_version, '4.4', '>=' ) ) { | |
| 149 | - return '7.0'; | |
| 150 | - } | |
| 135 | + return empty( array_diff( $steps, $completed_actions ) ); | |
| 136 | + } | |
| 151 | 137 | |
| 152 | - return '5.6'; | |
| 153 | - } | |
| 138 | + public function is_this_page( string $page ): bool { | |
| 154 | 139 | |
| 155 | - public function get_edit_site_url(): string { | |
| 156 | - if ( wp_is_block_theme() ) { | |
| 157 | - return add_query_arg( | |
| 158 | - array( | |
| 159 | - 'canvas' => 'edit', | |
| 160 | - ), | |
| 161 | - admin_url( 'site-editor.php' ) | |
| 162 | - ); | |
| 163 | - } | |
| 140 | + if ( ! isset( $_SERVER['REQUEST_URI'] ) ) { | |
| 141 | + return false; | |
| 142 | + } | |
| 164 | 143 | |
| 165 | - $show_on_front = get_option( 'show_on_front' ); | |
| 166 | - $front_page_id = get_option( 'page_on_front' ); | |
| 144 | + $current_uri = sanitize_text_field( $_SERVER['REQUEST_URI'] ); | |
| 167 | 145 | |
| 168 | - if ( $show_on_front === self::HOMEPAGE_DISPLAY && $front_page_id ) { | |
| 169 | - return add_query_arg( | |
| 170 | - array( | |
| 171 | - 'post' => $front_page_id, | |
| 172 | - 'action' => 'edit', | |
| 173 | - ), | |
| 174 | - admin_url( 'post.php' ) | |
| 175 | - ); | |
| 176 | - } | |
| 146 | + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { | |
| 147 | + return false; | |
| 148 | + } | |
| 177 | 149 | |
| 178 | - return ''; | |
| 179 | - } | |
| 150 | + if ( isset( $current_uri ) && strpos( $current_uri, '/wp-json/' ) !== false ) { | |
| 151 | + return false; | |
| 152 | + } | |
| 153 | + | |
| 154 | + if ( strpos( $current_uri, $page ) !== false ) { | |
| 155 | + return true; | |
| 156 | + } | |
| 157 | + | |
| 158 | + return false; | |
| 159 | + } | |
| 160 | + | |
| 161 | + public function get_promotional_link_url( string $locale ): string { | |
| 162 | + if ( isset( self::PROMOTIONAL_LINKS[ $locale ] ) ) { | |
| 163 | + return self::PROMOTIONAL_LINKS[ $locale ]; | |
| 164 | + } | |
| 165 | + | |
| 166 | + return self::PROMOTIONAL_LINKS['en_US']; | |
| 167 | + } | |
| 168 | + | |
| 169 | + public function get_hpanel_domain_url(): string { | |
| 170 | + $parsed_url = parse_url( get_site_url() ); | |
| 171 | + $host = $parsed_url['host']; | |
| 172 | + $host_parts = explode( '.', $host ); | |
| 173 | + $subdomain = ( count( $host_parts ) > 2 ) ? array_shift( $host_parts ) . '.' : ''; | |
| 174 | + $domain = implode( '.', $host_parts ); | |
| 175 | + | |
| 176 | + return self::HPANEL_DOMAIN_URL . $domain . ( $subdomain ? "/wordpress/dashboard/$subdomain$domain" : '' ); | |
| 177 | + } | |
| 178 | + | |
| 179 | + public function check_transient_eligibility( $transient_request_key, $cache_time = 3600 ): bool { | |
| 180 | + try { | |
| 181 | + // Set transient | |
| 182 | + set_transient( $transient_request_key, true, $cache_time ); | |
| 183 | + | |
| 184 | + // Check if transient was set successfully | |
| 185 | + if ( false === get_transient( $transient_request_key ) ) { | |
| 186 | + throw new Exception( 'Unable to create transient in WordPress.' ); | |
| 187 | + } | |
| 188 | + | |
| 189 | + // If everything is fine, return true | |
| 190 | + return true; | |
| 191 | + } catch ( Exception $exception ) { | |
| 192 | + // If there's an exception, log the error and return false | |
| 193 | + $this->error_log( 'Error checking eligibility: ' . $exception->getMessage() ); | |
| 194 | + | |
| 195 | + return false; | |
| 196 | + } | |
| 197 | + } | |
| 198 | + | |
| 199 | + public static function woocommerce_onboarding_choice(): bool { | |
| 200 | + return (bool) get_option( 'hostinger_woo_onboarding_choice', false ); | |
| 201 | + } | |
| 202 | + | |
| 203 | + /** | |
| 204 | + * @return bool | |
| 205 | + */ | |
| 206 | + public static function is_woocommerce_site(): bool { | |
| 207 | + return class_exists( 'WooCommerce' ); | |
| 208 | + } | |
| 209 | + | |
| 210 | + /** | |
| 211 | + * @return bool | |
| 212 | + */ | |
| 213 | + public static function show_woocommerce_onboarding(): bool { | |
| 214 | + $woo_onboarding_enabled = get_option( 'hostinger_woo_onboarding_enabled', false ); | |
| 215 | + $woo_setup_wizard_completed = get_option( 'woocommerce_onboarding_profile', false ); | |
| 216 | + | |
| 217 | + return ( self::is_woocommerce_site() && ! self::woocommerce_onboarding_choice() && $woo_onboarding_enabled && ! $woo_setup_wizard_completed ); | |
| 218 | + } | |
| 219 | + | |
| 220 | + /** | |
| 221 | + * @return bool | |
| 222 | + */ | |
| 223 | + public function can_show_store_ready_message(): bool { | |
| 224 | + if ( ! self::is_woocommerce_site() || ! self::woocommerce_onboarding_choice() ) { | |
| 225 | + return false; | |
| 226 | + } | |
| 227 | + | |
| 228 | + $store_ready_message_shown = get_option( 'hostinger_woo_ready_message_shown', null ); | |
| 229 | + | |
| 230 | + if ( $store_ready_message_shown === null ) { | |
| 231 | + return false; | |
| 232 | + } | |
| 233 | + | |
| 234 | + if ( (int) $store_ready_message_shown !== 0 ) { | |
| 235 | + return false; | |
| 236 | + } | |
| 237 | + | |
| 238 | + if ( ! $this->default_woocommerce_survey_completed() ) { | |
| 239 | + return false; | |
| 240 | + } | |
| 241 | + | |
| 242 | + return true; | |
| 243 | + } | |
| 244 | + | |
| 245 | + public function default_woocommerce_survey_completed(): bool { | |
| 246 | + $completed_actions = get_option( self::CLIENT_WOO_COMPLETED_ACTIONS, array() ); | |
| 247 | + $required_completed_actions = array( 'products', 'payments' ); | |
| 248 | + | |
| 249 | + return empty( array_diff( $required_completed_actions, $completed_actions ) ); | |
| 250 | + } | |
| 251 | + | |
| 180 | 252 | } |
| 253 | + | |
| 254 | +$hostinger_helper = new Helper(); | |