d $two_critical_pages = OptimizerUtils::getCriticalPages(); $url_query = $TwoSettings->get_settings('two_critical_url_args'); if (empty($two_critical_pages)) { $homeUrl = get_home_url(); $pageId = 'front_page'; $waitUntil = 'load'; $two_critical_default_settings = get_option('two_critical_default_settings'); if (isset($two_critical_default_settings['wait_until'])) { $waitUntil = $two_critical_default_settings['wait_until']; } $page_sizes = OptimizerUtils::get_critical_default_sizes($two_critical_default_settings); $data = [ 'action' => 'two_critical', 'data' => [ 'page_url' => $homeUrl, 'page_id' => $pageId, 'page_sizes' => $page_sizes, 'wait_until' => $waitUntil, 'url_query' => $TwoSettings->get_settings('two_critical_url_args'), 'task' => 'generate', 'newly_connected_website' => $rightAfterConnect, ], 'two_critical_sizes' => $TwoSettings->get_settings('two_critical_sizes'), 'two_critical_pages' => self::get_default_critical_pages(true), ]; if ($rightAfterConnect) { $data['data']['flow_id'] = get_site_option(TENWEB_PREFIX . '_flow_id'); } OptimizerCriticalCss::generateCriticalCSS($data); if (OptimizerUtils::is_wpml_active()) { OptimizerUtils::generate_wpml_home_pages_critical_css($data); } } else { $regenerate_data = \TenWebWpTransients\OptimizerTransients::get('two_regenerate_critical_data'); if (is_array($regenerate_data) && !empty($regenerate_data)) { $two_critical_pages = $regenerate_data; } else { if ('front_page' == $regeneration_mode) { // Invalidate all critical css. self::update_critical_statuses($two_critical_pages, 'not_started'); // Regenerate front page only. foreach ($two_critical_pages as $key => $two_page) { if ('front_page' != $key) { unset($two_critical_pages[$key]); } } } self::update_critical_statuses($two_critical_pages, 'in_progress'); } $two_critical_sizes = $TwoSettings->get_settings('two_critical_sizes'); if (!empty($two_critical_pages)) { $two_page = reset($two_critical_pages); $key = key($two_critical_pages); unset($two_critical_pages[$key]); $critical_sizes = []; if (isset($two_page['sizes']) && is_array($two_page['sizes'])) { foreach ($two_page['sizes'] as $size_id) { if (isset($size_id['uid'], $two_critical_sizes[$size_id['uid']]) && is_array($size_id)) { $critical_sizes[] = $two_critical_sizes[$size_id['uid']]; } } } $data = [ 'data' => [ 'page_url' => $two_page['url'], 'page_id' => $two_page['id'], 'page_sizes' => $critical_sizes, 'wait_until' => $two_page['wait_until'], 'url_query' => $url_query, 'task' => 'generate', 'newly_connected_website' => $rightAfterConnect, ], ]; if (isset($two_page['use_uncritical'])) { $data['data']['use_uncritical'] = $two_page['use_uncritical']; } OptimizerCriticalCss::generateCriticalCSS($data); $two_critical_pages_count = count($two_critical_pages); \TenWebWpTransients\OptimizerTransients::set('two_regenerate_critical_data', $two_critical_pages, 60 * $two_critical_pages_count); } } } public static function get_critical_default_sizes($critical_defaults) { global $TwoSettings; $new_sizes = []; $two_critical_sizes = $TwoSettings->get_settings('two_critical_sizes'); if (is_array($critical_defaults) && isset($critical_defaults['default_sizes'])) { foreach ($critical_defaults['default_sizes'] as $key) { if (isset($two_critical_sizes[$key])) { $new_sizes[$key] = $two_critical_sizes[$key]; } } } if (!empty($new_sizes)) { return array_keys($new_sizes); } return array_keys($two_critical_sizes); } public static function update_critical_statuses($two_critical_pages, $status) { global $TwoSettings; foreach ($two_critical_pages as $key => $two_page) { $two_critical_pages[$key]['status'] = $status; } $TwoSettings->update_setting('two_critical_pages', $two_critical_pages); } public static function init_defines() { global $TwoSettings; if (!defined('TWO_LAZYLOAD')) { define('TWO_LAZYLOAD', true); } if (!defined('TWO_WP_SITE_URL')) { if (function_exists('domain_mapping_siteurl')) { define('TWO_WP_SITE_URL', domain_mapping_siteurl(get_current_blog_id())); } else { define('TWO_WP_SITE_URL', site_url()); } } if (!defined('TWO_WP_CONTENT_URL')) { if (function_exists('get_original_url')) { define('TWO_WP_CONTENT_URL', str_replace(get_original_url(TWO_WP_SITE_URL), TWO_WP_SITE_URL, content_url())); } else { define('TWO_WP_CONTENT_URL', content_url()); } } if (!defined('TWO_WP_CONTENT_NAME')) { define('TWO_WP_CONTENT_NAME', '/' . wp_basename(WP_CONTENT_DIR)); } if (!defined('TWO_WP_ROOT_URL')) { define('TWO_WP_ROOT_URL', str_replace(TWO_WP_CONTENT_NAME, '', TWO_WP_CONTENT_URL)); } if (!defined('TWO_CACHE_URL')) { if (is_multisite()) { $blog_id = get_current_blog_id(); define('TWO_CACHE_URL', TWO_WP_CONTENT_URL . TENWEB_SO_CACHE_CHILD_DIR . $blog_id . '/'); } else { define('TWO_CACHE_URL', TWO_WP_CONTENT_URL . TENWEB_SO_CACHE_CHILD_DIR); } } if (!defined('WP_ROOT_DIR')) { define('WP_ROOT_DIR', substr(WP_CONTENT_DIR, 0, strlen(WP_CONTENT_DIR) - strlen(TWO_WP_CONTENT_NAME))); } if (!defined('TWO_HASH')) { define('TWO_HASH', wp_hash(TWO_CACHE_URL)); } if (!defined('TWO_CACHE_NOGZIP')) { $two_gzip = $TwoSettings->get_settings('two_gzip'); if (!TENWEB_SO_HOSTED_ON_10WEB && $two_gzip === 'on') { define('TWO_CACHE_NOGZIP', false); } else { define('TWO_CACHE_NOGZIP', true); } } if (!defined('TWO_CACHEFILE_PREFIX')) { define('TWO_CACHEFILE_PREFIX', 'two_'); } } public static function flushCloudflareCache($postId = null) { if (class_exists('\CF\WordPress\Hooks')) { $cloudflareHooks = new \CF\WordPress\Hooks(); if (is_int($postId)) { $cloudflareHooks->purgeCacheByRelevantURLs($postId); } else { $cloudflareHooks->purgeCacheEverything(); } } } public static function get_tenweb_connection_link($endpoint = 'sign-up', $args = []) { // copied from manager.py $return_url = get_admin_url() . 'admin.php'; if (is_multisite()) { $return_url = network_admin_url() . 'admin.php'; } $token = wp_create_nonce('two_10web_connection'); update_site_option(TW_OPTIMIZE_PREFIX . '_saved_nonce', $token); $return_url_args = ['page' => 'two_settings_page']; $register_url_args = [ 'site_url' => urlencode(get_site_url()), 'utm_source' => '10webspeedoptimizer', 'from_plugin' => self::FROM_PLUGIN, 'utm_medium' => 'freeplugin', 'nonce' => $token, 'subscr_id' => TENWEB_SO_FREE_SUBSCRIPTION_ID, 'version' => TENWEB_SO_VERSION, 'new_connection_flow' => 1, ]; if (!empty($args['old_connection_flow'])) { unset($register_url_args['new_connection_flow']); } if (!empty($args)) { $register_url_args = $register_url_args + $args; $return_url_args = $return_url_args + $args; } $register_url_args['return_url'] = urlencode(add_query_arg($return_url_args, $return_url)); $plugin_from = get_site_option('tenweb_manager_installed'); if ($plugin_from !== false) { $plugin_from = json_decode($plugin_from, true); if (is_array($plugin_from) && reset($plugin_from) !== false) { $register_url_args['plugin_id'] = reset($plugin_from); if (isset($plugin_from['type'])) { $register_url_args['utm_source'] = $plugin_from['type']; } } } $url = add_query_arg($register_url_args, TENWEB_DASHBOARD . '/' . $endpoint . '/'); return $url; } public static function getCriticalPages() { global $TwoSettings; if (empty($TwoSettings)) { return []; } $two_critical_pages_from_options = $TwoSettings->get_settings('two_critical_pages'); $two_critical_pages = self::get_meta_values('two_critical_pages'); if ($two_critical_pages_from_options) { $two_critical_pages = array_replace($two_critical_pages_from_options, $two_critical_pages); } return $two_critical_pages; } public static function stripslashes_deep($value) { // copied from wp-includes/formatting.php return self::map_deep($value, function ($value) { return is_string($value) ? stripslashes($value) : $value; }); } public static function map_deep($value, $callback) { // copied from wp-includes/formatting.php if (is_array($value)) { foreach ($value as $index => $item) { $value[$index] = self::map_deep($item, $callback); } } elseif (is_object($value)) { $object_vars = get_object_vars($value); foreach ($object_vars as $property_name => $property_value) { $value->$property_name = self::map_deep($property_value, $callback); } } else { $value = call_user_func($callback, $value); } return $value; } public static function get_meta_values($key = '') { if (empty($key)) { return null; } global $wpdb; $query = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $key)); // phpcs:ignore $result = []; foreach ($query as $row) { $result[ $row->post_id ] = unserialize($row->meta_value); // phpcs:ignore } return $result; } public static function check_if_hosted_website() { if (is_file(WPMU_PLUGIN_DIR . '/10web-manager/10web-manager.php')) { return true; } return false; } /* WPML functions*/ public static function get_wpml_home_urls() { if (!OptimizerUtils::is_wpml_active()) { return []; } $front_page_id = get_option('page_on_front'); // if $front_page_id is empty or 0, it means home page is archive page and there is no translation for that page if (!$front_page_id) { return []; } $element_id = $front_page_id; $element_type = get_post_type($front_page_id); $home_pages = []; $languages = apply_filters('wpml_active_languages', ''); foreach ($languages as $lang_code => $language_data) { $post_id = apply_filters('wpml_object_id', $element_id, $element_type, false, $lang_code); if (!$post_id) { continue; } $home_pages[$lang_code] = [ 'post_id' => $post_id, 'permalink' => get_permalink($post_id), 'title' => get_the_title($post_id) ]; } return $home_pages; } public static function add_wpml_home_pages_into_critical_pages($critical_pages = null, $home_url = null) { /* * The function added home pages generated by WPML into critical_pages list, if home page is in that list. The * function doesn't generate critical css. * */ global $TwoSettings; if ($critical_pages === null) { $critical_pages = OptimizerUtils::getCriticalPages(); } if ($home_url === null && $critical_pages['front_page']) { $home_url = $critical_pages['front_page']['url']; } if (!$home_url) { return $critical_pages; } foreach (OptimizerUtils::get_wpml_home_urls() as $lang_code => $post_data) { if (rtrim($post_data['permalink'], '/') === rtrim($home_url, '/')) { continue; } if (isset($critical_pages[$post_data['id']])) { continue; } $page_data = $critical_pages['front_page']; $page_data['title'] = $post_data['title']; $page_data['url'] = $post_data['permalink']; $page_data['id'] = $post_data['post_id']; $critical_pages[$post_data['post_id']] = $page_data; } $TwoSettings->update_setting('two_critical_pages', $critical_pages); return $critical_pages; } public static function generate_wpml_home_pages_critical_css($data) { self::add_wpml_home_pages_into_critical_pages(); $wpml_data = ['data' => $data['data']]; $home_page_url = $data['data']['page_url']; foreach (self::getCriticalPages() as $page) { if ($page['url'] == $home_page_url) { continue; } $is_wpml_page = false; foreach (self::get_wpml_home_urls() as $wpml_page) { if ($wpml_page['post_id'] == $page['id']) { $is_wpml_page = true; break; } } if ($is_wpml_page === false) { continue; } $wpml_data['data']['page_url'] = $page['url']; $wpml_data['data']['page_id'] = $page['id']; OptimizerCriticalCss::generateCriticalCSS($wpml_data); } } public static function get_wpml_post_flag_url($post_id) { if ($post_id == 'front_page') { $post_id = get_option('page_on_front'); } if (!$post_id) { $lang_code = apply_filters('wpml_default_language', null); } else { $post_language_details = apply_filters('wpml_post_language_details', null, $post_id); $lang_code = $post_language_details['language_code']; } return plugins_url('sitepress-multilingual-cms/res/flags/' . $lang_code . '.png'); } public static function is_wpml_active() { return defined('ICL_SITEPRESS_VERSION'); } public static function get_modes($name = null, $preview = false, $level = null) { $modes = self::MODES; if ($preview) { foreach ($modes as $key => $mode) { $modes[$key]['preview_url'] = add_query_arg(['two_preview' => '1', 'two_level' => $mode['level']], get_home_url() . '/'); } return $modes; } if (isset($name)) { return self::MODES[$name]; } elseif (isset($level)) { foreach ($modes as $key => $mode) { if ($mode['level'] === $level) { return $mode; } } } $global_mode = get_option('two_default_mode', OptimizerUtils::MODES['extreme']); if (is_array($global_mode)) { $modes['global'] = $global_mode; } return $modes; } public static function testWebPDelivery() { $requestUrl = TENWEB_SO_URL . '/test/webp_test.jpg'; $requestArgs = [ 'headers' => [ 'ACCEPT' => 'image/webp' ] ]; global $TwoSettings; $wpResult = wp_remote_get($requestUrl, $requestArgs); // phpcs:ignore if (!is_wp_error($wpResult)) { if (isset($wpResult['headers']['content-type']) && 'image/webp' === $wpResult['headers']['content-type']) { $TwoSettings->update_setting('two_webp_delivery_working', '1'); return true; } } $TwoSettings->update_setting('two_webp_delivery_working', '0'); return false; } public static function clear_third_party_cache() { global $wp_fastest_cache, $kinsta_cache, $nginx_purger; // if W3 Total Cache is being used, clear the cache if (function_exists('w3tc_pgcache_flush')) { w3tc_pgcache_flush(); } // if WP Super Cache is being used, clear the cache if (function_exists('wp_cache_clean_cache')) { global $file_prefix, $supercachedir; if (empty($supercachedir) && function_exists('get_supercache_dir')) { $supercachedir = get_supercache_dir(); } wp_cache_clean_cache($file_prefix); } if (class_exists('WpeCommon')) { //be extra careful, just in case 3rd party changes things on us if (method_exists('WpeCommon', 'purge_memcached')) { WpeCommon::purge_memcached(); } if (method_exists('WpeCommon', 'clear_maxcdn_cache')) { WpeCommon::clear_maxcdn_cache(); } if (method_exists('WpeCommon', 'purge_varnish_cache')) { WpeCommon::purge_varnish_cache(); } } if (method_exists('WpFastestCache', 'deleteCache') && !empty($wp_fastest_cache)) { $wp_fastest_cache->deleteCache(true); } if (class_exists('\Kinsta\Cache') && !empty($kinsta_cache) && !empty($kinsta_cache->kinsta_cache_purge)) { if (method_exists($kinsta_cache->kinsta_cache_purge, 'purge_complete_caches')) { $kinsta_cache->kinsta_cache_purge->purge_complete_caches(); } } if (class_exists('\WPaaS\Cache')) { if (!\WPaaS\Cache::has_ban()) { remove_action('shutdown', [ '\WPaaS\Cache', 'purge' ], PHP_INT_MAX); add_action('shutdown', [ '\WPaaS\Cache', 'ban' ], PHP_INT_MAX); } } if (class_exists('WP_Optimize') && defined('WPO_PLUGIN_MAIN_PATH')) { if (!class_exists('WP_Optimize_Cache_Commands')) { include_once WPO_PLUGIN_MAIN_PATH . 'cache/class-cache-commands.php'; } if (class_exists('WP_Optimize_Cache_Commands')) { $wpoptimize_cache_commands = new WP_Optimize_Cache_Commands(); $wpoptimize_cache_commands->purge_page_cache(); } } if (class_exists('Breeze_Admin')) { do_action('breeze_clear_all_cache'); } if (defined('LSCWP_V')) { do_action('litespeed_purge_all'); } // This function clears the Site Ground cache only if it is on in plugin. // As their hosting does not respect plugin's settings sometimes, maybe we'll need to call them directly. if (function_exists('sg_cachepress_purge_everything')) { sg_cachepress_purge_everything(); } if (class_exists('autoptimizeCache')) { autoptimizeCache::clearall(); } if (class_exists('Cache_Enabler')) { Cache_Enabler::clear_total_cache(); } if (defined('NGINX_HELPER_BASEPATH') && !empty($nginx_purger)) { $nginx_purger->purge_all(); } if (function_exists('rocket_clean_domain')) { rocket_clean_domain(); } if (defined('EZOIC_CACHE') && EZOIC_CACHE) { $cache = new \Ezoic_Namespace\Ezoic_Integration_Cache(); $cache->Clear(); } if (class_exists('Endurance_Page_Cache')) { $epc = new Endurance_Page_Cache(); $epc->force_purge = true; $epc->purge_all(); } } public static function two_flatten(array $array) { $return = []; array_walk_recursive($array, function ($a) use (&$return) { $return[] = $a; }); return $return; } public static function triggerPostOptimizationTasks($disabled_incompatible_plugins = []) { //todo new_flow_process this should be triggered manually when user clicks the apply mode button //todo new_flow_process disable test mode, apply mode, call post-optimization global $TwoSettings; $flow_id = get_site_option(TENWEB_PREFIX . '_flow_id'); $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); $two_conflicting_plugins = get_site_option('two_conflicting_plugins'); if (!is_array($two_conflicting_plugins)) { $two_conflicting_plugins = []; } if ($access_token && $domain_id) { $response = wp_remote_post(TENWEB_SO_CRITICAL_URL . '/v1/workspaces/performance/' . $domain_id . '/post-optimization-tasks', [ 'redirection' => 15, 'blocking' => false, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => [ 'notification_id' => sanitize_text_field($_POST['notification_id']), // phpcs:ignore 'flow_id' => $flow_id, 'disabled_incompatible_plugins' => $disabled_incompatible_plugins, 'incompatible_plugins' => $two_conflicting_plugins, 'has_excluded_slider' => false ], 'cookies' => [] ]); update_option('two_critical_data_import_response_' . time(), [ !is_wp_error($response) ? $response['body'] : $response->get_error_message(), wp_remote_retrieve_response_code($response) ], false); } } public static function check_score() { $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); $workspace_id = get_site_option(TENWEB_PREFIX . '_workspace_id'); if ($access_token && $domain_id && $workspace_id) { wp_remote_post(TENWEB_SO_CRITICAL_URL . '/v1/workspaces/' . $workspace_id . '/performance/' . $domain_id . '/googlepagespeed', [ 'redirection' => 15, 'blocking' => false, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => [ ], 'cookies' => [] ]); } } public static function set_global_mode() { global $TwoSettings; $modes = self::get_modes(); $two_critical_status = $TwoSettings->get_settings('two_critical_status'); $two_delay_all_js_execution = $TwoSettings->get_settings('two_delay_all_js_execution'); if ($two_critical_status == 'true' && $two_delay_all_js_execution == 'on') { $mode = 'extreme'; } elseif ($two_critical_status == 'true' && $two_delay_all_js_execution != 'on') { $mode = 'balanced'; } elseif ($two_critical_status != 'true' && $two_delay_all_js_execution === 'on') { $mode = 'strong'; } else { $mode = 'standard'; } if (isset($modes[$mode])) { foreach ($modes[$mode] as $key => $val) { if (isset($settings_names[$key])) { $TwoSettings->update_setting($key, $val); } elseif ($key === 'critical_enabled') { if ($val) { $TwoSettings->update_setting('two_critical_status', 'true'); } else { $TwoSettings->update_setting('two_critical_status', ''); } } } update_option('two_default_mode', $modes[$mode]); } } /** * @return int|string page_id|front_page|term_$term_id */ public static function get_current_post_info() { $queried_object = get_queried_object(); $id = 0; if (is_front_page()) { $id = 'front_page'; } elseif (class_exists('WooCommerce') && is_shop()) { $id = wc_get_page_id('shop'); } elseif ($queried_object instanceof WP_Term) { $id = 'term_' . $queried_object->term_id; } elseif ($queried_object instanceof WP_User) { $id = 'user_' . $queried_object->ID; } elseif ($queried_object instanceof \WP_Post) { $id = $queried_object->ID; } if ($id === 0) { global $wp; $home_url = trailingslashit(home_url($wp->request)); $db_home_url = trailingslashit(get_home_url()); if ($home_url === $db_home_url) { $id = 'front_page'; } } return $id; } public static function get_permalink_name_by_id($id = 'front_page') { if ('front_page' === $id) { return [ 'url' => home_url(), 'title' => 'Home' ]; } else { if (0 === strpos($id, 'term_')) { $term_id = (int) ltrim ($id, 'term_'); $term = get_term($term_id); return [ 'url' => get_term_link($term_id), 'title' => $term->name ]; } elseif (0 === strpos($id, 'user_')) { $user_id = (int) ltrim ($id, 'user_'); return [ 'url' => get_author_posts_url($user_id), 'title' => get_the_author_meta('nicename', $user_id) ]; } else { return [ 'url' => get_permalink($id), 'title' => get_the_title($id) ]; } } } public static function remove_url_protocol($url) { $url = rtrim($url, '/'); $disallowed = ['http://www.', 'https://www.', 'http://', 'https://']; foreach ($disallowed as $d) { if (strpos($url, $d) === 0) { return str_replace($d, '', $url); } } return $url; } public static function get_post_id($page_url = null) { $pageUrlHash = md5((string) $page_url); // this function is called in a loop to replace backgrounds, in order not to make a thousand requests to website to find page_id we will cache it in globals //phpcs:ignore PHPCompatibility.Variables.ForbiddenGlobalVariableVariable.NonBareVariableFound global ${'two_current_page_id' . $pageUrlHash}; if (!empty(${'two_current_page_id' . $pageUrlHash})) { return ${'two_current_page_id' . $pageUrlHash}; } $home_url = rtrim(get_home_url(), '/'); $page_url = rtrim((string) $page_url, '/'); $id = 0; if (!empty($page_url)) { if (self::remove_url_protocol($home_url) === self::remove_url_protocol($page_url)) { return 'front_page'; } $id = url_to_postid($page_url); // phpcs:ignore if ($id === 0 && class_exists('WooCommerce')) { $shop_page_id = wc_get_page_id('shop'); $shop_page_url = rtrim(get_permalink(wc_get_page_id('shop')), '/'); if ($shop_page_url === $page_url) { $id = $shop_page_id; } } if ($id === 0) { $page_for_posts = get_option('page_for_posts'); $post_page_id = (int) $page_for_posts; $post_page_url = rtrim(get_permalink($post_page_id), '/'); if ($post_page_url === $page_url) { $id = $post_page_id; } } if (0 === $id) { $page_headers = wp_get_http_headers(add_query_arg([ 'two_detect_post_id' => '1' ], $page_url)); $id = isset($page_headers[ 'x-two-post-id' ]) ? $page_headers[ 'x-two-post-id' ] : 0; } ${'two_current_page_id' . $pageUrlHash} = $id; } else { ${'two_current_page_id' . $pageUrlHash} = self::get_current_post_info(); } return ${'two_current_page_id' . $pageUrlHash}; } public static function two_update_subscription() { $tenweb_subscription_id = false; $tenweb_plan_title = false; $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); $workspace_id = get_site_option(TENWEB_PREFIX . '_workspace_id'); if (!empty($access_token) && !empty($domain_id) && !empty($workspace_id)) { $response = wp_remote_post(TENWEB_SO_CRITICAL_URL . '/v1/workspaces/' . $workspace_id . '/domains/' . $domain_id . '/get_subscription', [ 'timeout' => 5, // phpcs:ignore 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => [], 'cookies' => [] ]); if (!is_wp_error($response) && isset($response['body'], $response['response']['code']) && $response['response']['code'] === 200) { $response_body = json_decode($response['body'], true); if ($response_body['data']['success']) { if (isset($response_body['data']['subscription_id'])) { $tenweb_subscription_id = $response_body['data']['subscription_id']; \TenWebWpTransients\OptimizerTransients::set(TENWEB_PREFIX . '_subscription_id', $tenweb_subscription_id, 12 * HOUR_IN_SECONDS); } if (isset($response_body['data']['plan_title'])) { $tenweb_plan_title = $response_body['data']['plan_title']; $tenweb_plan_title = strtolower($tenweb_plan_title) == 'speed' ? 'Free' : $tenweb_plan_title; //sometimes we get 'speed' from service, it means free if (in_array((int) $tenweb_subscription_id, TENWEB_SO_FREE_SUBSCRIPTION_IDS)) { $tenweb_plan_title = 'Free'; } \TenWebWpTransients\OptimizerTransients::set(TENWEB_PREFIX . '_plan_title', $tenweb_plan_title, 12 * HOUR_IN_SECONDS); } if (isset($response_body['data']['referral_hash'])) { $referral_hash = $response_body['data']['referral_hash']; if (!empty($referral_hash)) { update_site_option(TENWEB_PREFIX . '_client_referral_hash', $referral_hash); } } } } elseif (is_wp_error($response) || !isset($response['body'], $response['response']['code']) || $response['response']['code'] !== 429) { \TenWebWpTransients\OptimizerTransients::set(TENWEB_PREFIX . '_subscription_id', '0', HOUR_IN_SECONDS); \TenWebWpTransients\OptimizerTransients::set(TENWEB_PREFIX . '_plan_title', '', HOUR_IN_SECONDS); } } return compact('tenweb_subscription_id', 'tenweb_plan_title'); } public static function two_critical_status($page_id = false) { global $TwoSettings; $two_critical_pages = self::getCriticalPages(); if (is_array($two_critical_pages)) { if ($page_id === false) { foreach ($two_critical_pages as $critical_page) { self::two_critical_status($critical_page['id']); } } elseif (isset($two_critical_pages[$page_id])) { $critical_in_progress_key = 'two_critical_in_progress_' . $page_id; $critical_in_progress = \TenWebWpTransients\OptimizerTransients::get($critical_in_progress_key); if ($critical_in_progress !== '1') { if (isset($two_critical_pages[$page_id]['status']) && $two_critical_pages[$page_id]['status'] == 'in_progress') { $two_critical_pages[$page_id]['status'] = 'not_started'; $TwoSettings->update_setting('two_critical_pages', $two_critical_pages); } } } } } public static function two_redirect($url, $exit = true) { while (ob_get_level() !== 0) { ob_end_clean(); } wp_redirect($url); //phpcs:ignore WordPressVIPMinimum.Security.ExitAfterRedirect.NoExit if ($exit) { exit(); } } public static function check_page_has_no_redirects($url, $arg = true) { if ($arg) { $url = add_query_arg([ 'two_check_redirect' => '1', ], $url); } $response = wp_remote_head($url, [ 'timeout' => 20, // phpcs:ignore 'redirection' => 0, 'httpversion' => '1.0', 'blocking' => true, 'sslverify' => false ]); if (!is_wp_error($response)) { $headers = $response[ 'headers' ]; if (isset($headers[ 'Location' ])) { $location = $headers[ 'Location' ]; if (!empty($location)) { if (is_array($location)) { $location = end($location); } $redirect_url_parse = wp_parse_url($location); $main_url_parse = wp_parse_url($url); if (isset($redirect_url_parse[ 'host' ]) && isset($main_url_parse[ 'host' ])) { if ($redirect_url_parse[ 'host' ] === $main_url_parse[ 'host' ]) { return true; } } return false; } return false; } } return true; } public static function is_paid_user() { global $tenweb_subscription_id; return (defined('TENWEB_SO_HOSTED_ON_10WEB') && TENWEB_SO_HOSTED_ON_10WEB) || (defined('TENWEB_SO_FREE_SUBSCRIPTION_IDS') && (!in_array((int) $tenweb_subscription_id, TENWEB_SO_FREE_SUBSCRIPTION_IDS))); } public static function is_tenweb_booster_connected() { return (defined('TENWEB_SO_HOSTED_ON_10WEB') && TENWEB_SO_HOSTED_ON_10WEB) || (defined('TENWEB_CONNECTED_SPEED') && \Tenweb_Authorization\Login::get_instance()->check_logged_in() && \Tenweb_Authorization\Login::get_instance()->get_connection_type() == TENWEB_CONNECTED_SPEED && !empty(get_option('two_first_connect'))); } /** * For hosting cache , run only connected sites **/ public static function update_post($id = 0) { if (TENWEB_SO_HOSTED_ON_10WEB) { return; } if ($id === 0) { $id = get_option('page_on_front'); if ($id === '0' || $id === 0) { $recent_post = wp_get_recent_posts([ 'numberposts' => 1, 'post_type' => 'post', 'post_status' => 'publish', ], OBJECT); if (is_array($recent_post) && isset($recent_post[0]->ID)) { $id = $recent_post[0]->ID; } } } if ($id !== 0) { $post_data = ['ID' => $id]; // removing kses_filter to avoid striping script or style tags from gutenberg editor remove_filter('content_save_pre', 'wp_filter_post_kses'); wp_update_post(wp_slash($post_data)); add_filter('content_save_pre', 'wp_filter_post_kses'); } } /** * For not hosted sites **/ public static function set_critical() { if (isset($_POST['token'], $_POST['page_id']) && get_option('two_critical' . sanitize_text_field($_POST['page_id'])) === $_POST['token']) { // phpcs:ignore \TenWebWpTransients\OptimizerTransients::delete('two_critical' . sanitize_text_field($_POST['page_id'])); // phpcs:ignore if (isset($_FILES['covered_css']) && isset($_FILES['covered_css']['tmp_name'])) { //TODO: maybe sanitization must be implemented $uploadfile = $_FILES['covered_css']['tmp_name']; // phpcs:ignore \TenWebWpTransients\OptimizerTransients::delete('two_critical_in_process'); $triggerPostOptimizationTasks = !empty($_POST['newly_connected_website']) && !empty($_POST['notification_id']); // phpcs:ignore update_option('two_critical_data_import_data_' . time(), $triggerPostOptimizationTasks, false); \TenWebOptimizer\OptimizerCriticalCss::createCriticalCSS($uploadfile, $triggerPostOptimizationTasks); echo '{"status":"ok"}'; die(0); } die('no covered_css data'); } die('Invalid token'); } public static function download_critical() { if (isset($_GET['two_update_critical'], $_GET['page_id']) && $_GET['two_update_critical'] === '1') { // phpcs:ignore $return_data = [ 'success' => false, 'message' => 'error' ]; $page_id = sanitize_text_field($_GET['page_id']); // phpcs:ignore $triggerPostOptimizationTasks = !empty($_GET['newly_connected_website']) && !empty($_GET['notification_id']); // phpcs:ignore $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); $file_content_response = wp_remote_get(TENWEB_SO_CRITICAL_URL . '/v1/critical/' . $domain_id . '/pages/' . $page_id . '/get', [ // phpcs:ignore 'timeout' => 5, // phpcs:ignore 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'cookies' => [] ]); if (!is_wp_error($file_content_response) && isset($file_content_response['body'])) { $file_content = $file_content_response['body']; $file_content_arr = json_decode($file_content, true); if (isset($file_content_arr['data']['data']['covered_css']['value'])) { \TenWebOptimizer\OptimizerCriticalCss::createCriticalCSS(false, $triggerPostOptimizationTasks, $file_content_arr['data']['data']['covered_css']['value'], true); $return_data['success'] = true; $return_data['message'] = 'success'; } } echo json_encode($return_data); // phpcs:ignore die; } } public static function update_connection_flow_progress($status, $step, $metaData = []) { $flow_id = get_site_option(TENWEB_PREFIX . '_flow_id'); $notification_id = get_site_option(TENWEB_PREFIX . '_notification_id'); $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); if ($access_token && $domain_id) { $response = wp_remote_post(TENWEB_SO_CRITICAL_URL . '/v1/domains/' . $domain_id . '/update_connection_flow_progress', [ 'timeout' => 89, // phpcs:ignore 'redirection' => 15, 'blocking' => true, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => [ 'flow_id' => $flow_id, 'notification_id' => $notification_id, 'status' => $status, 'step' => $step, 'debug_data' => $metaData ], 'cookies' => [] ]); } } public static function filter_incompatible_plugins($plugins) { $two_incompatible_plugin_list = self::TWO_INCOMPATIBLE_PLUGIN_LIST; $return_list = [ 'incompatible' => [], 'compatible' => [], ]; foreach ($plugins as $plugin) { $key = array_search($plugin, $two_incompatible_plugin_list, true); if ($key) { $return_list['incompatible'][] = $two_incompatible_plugin_list[$key]; } else { $return_list['compatible'][] = $plugin; } } return $return_list; } public static function get_conflicting_plugins() { $two_incompatible_plugin_list = self::TWO_INCOMPATIBLE_PLUGIN_LIST; $active_plugins = get_option('active_plugins'); $all_plugins = get_plugins(); $incompatible_active_plugin_slugs = array_intersect($two_incompatible_plugin_list, $active_plugins); $incompatible_active_plugin_list = []; foreach ($incompatible_active_plugin_slugs as $plugin) { $incompatible_active_plugin_list[$plugin] = $all_plugins[$plugin]['Name']; } return $incompatible_active_plugin_list; } public static function injectCriticalBg($content, $critical, $cacheStructure) { if (isset($_GET['no_critical_css']) && $_GET['no_critical_css'] == 1) { // phpcs:ignore return $content; } global $TwoSettings; $two_serve_optimized_bg_image = $TwoSettings->get_settings('two_serve_optimized_bg_image'); if ($two_serve_optimized_bg_image === 'on') { if (isset($critical) && isset($critical->critical_bg) && !empty($critical->critical_bg)) { $critical_bg_file_dir = TWO_CACHE_DIR . 'critical/' . $critical->critical_bg; if (file_exists($critical_bg_file_dir)) { $critical_bg_data = file_get_contents($critical_bg_file_dir); // phpcs:ignore $critical_bg_data_arr = json_decode($critical_bg_data, true); $critical_bg_css = self::serve_different_sizes_for_critical_bg_image($critical_bg_data_arr); if (!empty($critical_bg_css)) { $critical_bg_css = "'; } } } } if (isset($critical_bg_css) && !empty($critical_bg_css)) { $content = OptimizerUtils::inject_in_html($content, $critical_bg_css, ['', 'before']); $cacheStructure->addToTagsToAdd($critical_bg_css, ['', 'before']); } return $content; } public static function delete_define($key, $content) { $re = '/define\s*\(\s*[\'\"](' . $key . ')[\'\"].?,(.*?)\);/'; preg_match_all($re, $content, $matches, PREG_SET_ORDER, 0); if (is_array($matches)) { foreach ($matches as $define_arr) { if (isset($define_arr[0], $define_arr[1]) && $define_arr[1] == 'WP_CACHE') { $content = str_replace($define_arr[0], '', $content); } } } return $content; } public static function check_plugin_update() { $plugins = get_site_transient('update_plugins'); if (isset($plugins->response) && is_array($plugins->response)) { foreach ($plugins->response as $plugin_data) { if (isset($plugin_data->slug) && $plugin_data->slug === 'tenweb-speed-optimizer') { return true; } } } return false; } public static function clear_cloudflare_cache($prefixes = [], $clear_cache_from = '') { global $TwoSettings; $cloudflare_cache_status = $TwoSettings->get_settings('cloudflare_cache_status'); if (($cloudflare_cache_status !== 'on' || TENWEB_SO_HOSTED_ON_10WEB) && $clear_cache_from != 'settings_page') { return true; } $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); $workspace_id = get_site_option(TENWEB_PREFIX . '_workspace_id'); $req_body = []; $req_body['prefixes'] = $prefixes; if (isset($access_token, $domain_id, $workspace_id) && !empty($access_token) && !empty($domain_id) && !empty($workspace_id)) { $response = wp_remote_post(TENWEB_SO_CRITICAL_URL . '/v1/workspaces/' . $workspace_id . '/domains/' . $domain_id . '/clear_cloudflare_cache', [ 'timeout' => 1, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => false, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => $req_body, 'cookies' => [] ]); } return true; } public static function has_changed_bg_image() { return self::$has_changed_bg_image; } public static function delete_critical_page($page_id) { global $TwoSettings; $critical_key = 'two_critical_' . $page_id; $critical_in_progress_key = 'two_critical_in_progress_' . $page_id; \TenWebWpTransients\OptimizerTransients::delete($critical_key); \TenWebWpTransients\OptimizerTransients::delete($critical_in_progress_key); $two_critical_all_pages = OptimizerUtils::getCriticalPages(); if (OptimizerUrl::isCriticalSavedInSettings($page_id)) { $two_critical_pages = $TwoSettings->get_settings('two_critical_pages'); unset($two_critical_pages[$page_id]); unset($two_critical_pages['']); $TwoSettings->update_setting('two_critical_pages', $two_critical_pages); } else { delete_post_meta($page_id, 'two_critical_pages'); } $prefix = 'critical/two_' . $page_id . '_*.*'; self::delete_files_by_prefix($prefix); $tenweb_subscription_id = \TenWebWpTransients\OptimizerTransients::get(TENWEB_PREFIX . '_subscription_id'); $is_free = (in_array((int) $tenweb_subscription_id, TENWEB_SO_FREE_SUBSCRIPTION_IDS) && !TENWEB_SO_HOSTED_ON_10WEB); if (is_array($two_critical_all_pages) && isset($two_critical_all_pages[$page_id]) && $is_free) { self::delete_so_page($page_id); } } public static function delete_so_page($page_id) { $domain_id = get_site_option('tenweb_domain_id'); $access_token = get_site_option(TENWEB_PREFIX . '_access_token'); $workspace_id = get_site_option(TENWEB_PREFIX . '_workspace_id'); if ($access_token && $domain_id && $workspace_id) { wp_remote_post(TENWEB_SO_CRITICAL_URL . '/v1/workspaces/' . $workspace_id . '/domains/' . $domain_id . '/delete-so-page', [ 'timeout' => 5, // phpcs:ignore 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => [ 'pageId' => $page_id ], 'cookies' => [] ]); } } public static function update_site_state() { $domain_id = get_option('tenweb_domain_id'); if ($domain_id) { global $wp_version, $wpdb; $sql_version = $wpdb->get_var('SELECT VERSION() AS version'); // phpcs:ignore $home_url = get_home_url(); $admin_url = get_admin_url(); $site_title = get_bloginfo('name'); $url = TENWEB_API_URL . '/site-state/' . $domain_id; $site_info = [ 'site_info' => [ 'platform' => 'wordpress', 'site_url' => $home_url, 'admin_url' => $admin_url, 'name' => $home_url, 'site_title' => $site_title, 'site_screenshot_url' => $home_url, 'platform_version' => $wp_version, 'php_version' => PHP_VERSION, 'mysql_version' => $sql_version, 'manager_version' => get_site_option(TENWEB_PREFIX . '_from_image_optimizer') ? 'iowd_' . TENWEBIO_PREFIX : TENWEB_VERSION, 'other_data' => [ 'manager_version' => TENWEB_VERSION, ] ] ]; $args = [ 'method' => 'POST', 'body' => ['data' => $site_info] ]; $Helper = \Tenweb_Authorization\Helper::get_instance(); return $Helper->request($url, $args, 'send_site_state'); } } public static function init_flow_score_check($only_do_request = false) { if ($only_do_request) { $nonce = uniqid('two_', false); update_option('wp_two_nonce_two_init_flow_score', $nonce); $res = wp_remote_post(admin_url('admin-ajax.php'), [ 'timeout' => 5, // phpcs:ignore 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => false, 'body' => [ 'action' => 'two_init_flow_score', 'nonce' => $nonce ], 'cookies' => [] ]); return; } $flow_score_check_init = get_option('flow_score_check_init', false); $two_flow_speed = get_option('two_flow_speed', false); if ($flow_score_check_init !== '1' && !is_array($two_flow_speed) && !\Tenweb_Authorization\Login::get_instance()->check_logged_in()) { update_option('flow_score_check_init', '1'); self::add_log_for_score_check_flow('init_flow_score_check', 'start two_google_check_score'); \TenWebSC\TWScoreChecker::twsc_check_score('front_page', $old = true, $no_optimized = true); $score_data = get_option('two-front-page-speed'); $speed_data['nooptimize_score'] = []; if (isset($score_data['previous_score']['desktop_score'], $score_data['previous_score']['desktop_tti'])) { $speed_data['nooptimize_score']['desktopScore'] = $score_data['previous_score']['desktop_score']; $speed_data['nooptimize_score']['desktopTti'] = $score_data['previous_score']['desktop_tti']; } if (isset($score_data['previous_score']['mobile_score'], $score_data['previous_score']['mobile_tti'])) { $speed_data['nooptimize_score']['mobileScore'] = $score_data['previous_score']['mobile_score']; $speed_data['nooptimize_score']['mobileTti'] = $score_data['previous_score']['mobile_tti']; } $speed_data['nooptimize_score']['tool'] = 'pageSpeedInsight'; $speed_data['nooptimize_score']['two_version'] = TENWEB_SO_VERSION; $speed_data['nooptimize_score']['desktopData'] = []; $speed_data['nooptimize_score']['mobileData'] = []; update_site_option('two_flow_speed', $speed_data); } global $wpdb; $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", TENWEB_PREFIX . '_access_token')); // phpcs:ignore $access_token = false; if (is_object($row) && isset($row->option_value)) { $access_token = $row->option_value; } $two_flow_speed = get_option('two_flow_speed', false); self::add_log_for_score_check_flow('two_flow_speed', $two_flow_speed); if ($access_token && is_array($two_flow_speed) && isset($two_flow_speed['nooptimize_score']['mobileScore'], $two_flow_speed['nooptimize_score']['desktopScore'])) { $domain_id = get_site_option('tenweb_domain_id'); $flow_id = get_site_option(TENWEB_PREFIX . '_flow_id', false); $workspace_id = get_site_option(TENWEB_PREFIX . '_workspace_id'); $route = TENWEB_SO_CRITICAL_URL . '/v1/workspaces/' . $workspace_id . '/domains/' . $domain_id . '/set_nooptimize_score'; $body = $two_flow_speed; $body['check_with_no_optimization'] = true; $body['flow_id'] = $flow_id; $body['is_first_optimization_flow'] = false; self::add_log_for_score_check_flow('send_data_to_performance', 'start send_data_to_performance'); self::send_data_to_performance($route, $body, $access_token); } } public static function send_data_to_performance($route, $body, $access_token) { $res = wp_remote_post($route, [ 'timeout' => 10, // phpcs:ignore 'redirection' => 10, 'httpversion' => '1.0', 'blocking' => true, 'headers' => [ 'accept' => 'application/x.10webperformance.v1+json', 'authorization' => 'Bearer ' . $access_token, ], 'body' => $body, 'cookies' => [] ]); } public static function add_log_for_score_check_flow($key, $val) { $two_flow_score_log = get_option('two_flow_score_log', []); $flag = 1; if (isset($two_flow_score_log['flag'])) { $flag = (int) $two_flow_score_log['flag']; $flag ++; } $arr_key = $flag . '_' . $key; $two_flow_score_log[$arr_key] = $val; $two_flow_score_log['flag'] = $flag; update_option('two_flow_score_log', $two_flow_score_log); } public static function warmup_cache() { if (!self::check_if_hosted_website()) { $site_url = site_url() . '?tenweb_warmup_cache=1&tenweb_version=' . TENWEB_SO_VERSION . '&warmup_time=' . time(); wp_remote_get($site_url, ['sslverify' => false, 'blocking' => false, 'timeout' => 0.1]); // phpcs:ignore } } public static function get_absolute_url($url) { $parsed = parse_url($url); // phpcs:ignore $path = $parsed['path']; if (!str_contains($path, '..')) { return $url; } // fix dots in relative path $path_parts = explode('/', $path); $absolutes = []; foreach ($path_parts as $part) { if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } return str_replace($parsed['path'], implode('/', $absolutes), $url); } public static function IOConnected() { return get_site_option(TENWEB_PREFIX . '_from_image_optimizer'); } public static function TWOConnected() { return get_option('two_first_connect'); } public static function request_webp_action($task, $url_list = '') { try { if ('regenerate' === $task) { $image_list = []; $page_list = []; foreach (explode(' ', $url_list) as $url) { if (0 === strpos($url, site_url())) { if (preg_match('/\.(jpg|png|jpeg)$/', $url)) { $image_list[] = $url; } else { $page_list[] = $url . (strpos($url, '?') > -1 ? '&' : '?') . 'two_nooptimize=1'; } } } if (empty($image_list) || TENWEB_SO_HOSTED_ON_10WEB) { $request_data = [ 'force_convert' => 0, 'quality' => 50, 'image_list' => implode(',', $image_list), 'url_list' => implode(',', $page_list), 'site_url' => site_url(), ]; $method = 'POST'; $endpoint = \TenWebIO\Api::API_WEBP_CONVERT; $api_instance = new \TenWebIO\Api($endpoint); $response = $api_instance->apiRequest($method, $request_data); if (false !== $response) { $response_data = [ 'status' => 'success', ]; } else { $response_data = [ 'status' => 'error', 'error' => false ]; } } else { //if we have array of urls, and website is not hosted on 10Web call internal IO classes to optimize them $compressService = new CompressService(); $compressService->compressCustom($image_list, 'front_page', 1); $response_data = [ 'status' => 'success', ]; } } elseif ('delete' === $task) { $count = \TenWebIO\Utils::deleteWebPImages(); $response_data = [ 'status' => 'success', 'count' => $count ]; } else { $response_data = [ 'status' => 'error', 'error' => 'Invalid Task' ]; } } catch (Exception $e) { $response_data = [ 'status' => 'error', 'error' => $e->getMessage() ]; } return $response_data; // phpcs:ignore } public static function check_admin_capabilities() { return current_user_can('manage_options'); } }