<?php 
class keyspider_common{
    public function init(){
        add_action('wp', [$this,'keyspider_init_session']);

        if(is_admin()){
            add_action( 'admin_enqueue_scripts', [$this,'keyspider_enqueue'] );
            add_filter('plugin_action_links_'.KEYSPIDER_NAME, [$this,'spider_plugin_action_links']);
            add_action('admin_menu', [$this,'keyspider_addpages']);
        }else{
            add_action('wp_footer', [$this,'keyspider_wztkjseo']);
        }
        add_action('wp_ajax_keyspider_liuliang_log', [$this,'keyspider_liuliang_log']);
        add_action('wp_ajax_nopriv_keyspider_liuliang_log', [$this,'keyspider_liuliang_log']);
        add_filter('keyspider_dhdfkdksj', [$this,'keyspider_dhdfkdksj']);
        add_filter('keyspider_dssdd', [$this,'keyspider_dssdd']);
        
         add_filter('cron_schedules', [$this,'keyspider_cron_ts_verey']);

    }
    public function keyspider_cron_ts_verey($schedules){
          
        if (!isset($schedules['keyspider_every_five_minute'])) {
            $schedules['keyspider_every_five_minute'] = array(
                'interval' => 300,
                'display'  => __('Every five Minute', 'keyspider')
            );
        }
        return $schedules;
    
    }
    public function keyspider_init_session(){
        if (!session_id()) {
            ob_start();
            session_start();
            ob_end_flush();
        }
    }
     public function keyspider_liuliang_log(){
        if(isset($_POST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])),'keyspider')){
            global $wpdb;
            $currnetTime = current_time('Y-m-d H:i:s');
            $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : '';

            if (empty($userAgent)) {
                return;
            }

            $botKeywords = [
                'bot', 'crawl', 'spider', 'slurp', 'search', 'fetch', 'index',
                'googlebot', 'bingbot', 'yandexbot', 'baiduspider', 'sogou', 'exabot',
                'msnbot', 'mj12bot', 'ahrefs', 'semrush'
            ];
            $isBot = false;
            foreach ($botKeywords as $keyword) {
                if (strpos($userAgent, $keyword) !== false) {
                    $isBot = true;
                    break;
                }
            }
            if ($isBot) {
                return;
            }
            global $wpdb;
            $currnetTime = current_time('Y-m-d H:i:s');
            $today = current_time('Y-m-d');

            $params = [
                'userAgent' => isset($_POST['userAgent']) ? sanitize_text_field(wp_unslash($_POST['userAgent'])) : '',
                'allCookies' => isset($_POST['allCookies']) ? sanitize_text_field(wp_unslash($_POST['allCookies'])) : '',
                'ip' => isset($_POST['ip']) ? sanitize_text_field(wp_unslash($_POST['ip'])) : '',
                'currentUrl' => isset($_POST['currentUrl']) ? sanitize_url(wp_unslash($_POST['currentUrl'])) : '',
                'referrer' => isset($_POST['referrer']) ? sanitize_url(wp_unslash($_POST['referrer'])) : '',
                'keyspider_time' => isset($_POST['keyspider_time']) ? sanitize_text_field(wp_unslash($_POST['keyspider_time'])) : '',

                'keyspider_language' => isset($_POST['keyspider_language']) ? sanitize_text_field(wp_unslash($_POST['keyspider_language'])) : '',
                'keyspider_pla' => isset($_POST['keyspider_pla']) ? sanitize_text_field(wp_unslash($_POST['keyspider_pla'])) : '',
                'keyspider_liulanqi' => isset($_POST['keyspider_liulanqi']) ? sanitize_text_field(wp_unslash($_POST['keyspider_liulanqi'])) : '',
                'keyspider_type' => isset($_POST['keyspider_type']) ? (int)$_POST['keyspider_type'] : 0,
                'keyspider_detail' => isset($_POST['keyspider_detail']) ? sanitize_text_field(wp_unslash($_POST['keyspider_detail'])) : '',
            ];
            $params['session'] = $session = md5(
                $params['userAgent'] .
                    $params['allCookies'] .
                    $params['ip'] .
                    $params['currentUrl'] .
                    $params['referrer'] .
                    $params['keyspider_time']
            );

            $shibie = md5($params['userAgent'] . $params['allCookies'] . $params['ip']);
            $existing_record = $wpdb->get_row($wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}keyspider_liuliang 
                 WHERE session = %s",
                $session,
            ), ARRAY_A);

            if ($existing_record) {
                $wpdb->update(
                    $wpdb->prefix . 'keyspider_liuliang',
                    ['updatetime' => $currnetTime],
                    ['id' => $existing_record['id']]
                );
                return;
            }
            $has_today_record = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}keyspider_liuliang 
                 WHERE shibie = %s AND DATE(time) = %s",
                $shibie,
                $today
            ));
            $status = empty($has_today_record) ? 1 : 0;
            $ip_exists = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}keyspider_liuliang 
                 WHERE ip = %s",
                $params['ip']
            ));
            $is_new = $ip_exists > 0 ? 1 : 0;

            $today_pinci = (int)$wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}keyspider_liuliang 
                 WHERE shibie = %s AND DATE(time) = %s",
                $shibie,
                $today
            ));
            $pinci = $today_pinci + 1;

            $first_record = $wpdb->get_row($wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}keyspider_liuliang 
                 WHERE shibie = %s AND DATE(time) = %s AND status = 1 
                 ORDER BY id ASC LIMIT 1",
                $shibie,
                $today
            ), ARRAY_A);


            $insert_data = [
                'source' => $params['referrer'] ? $params['referrer'] : '隐匿来源',
                'url' => $params['currentUrl'],
                'time' => $currnetTime,
                'ip' => $params['ip'] === 'unknown' ? '' : $params['ip'],
                'shibie' => $shibie,
                'session' => $params['session'],
                'type' => $params['keyspider_type'],
                'status' => $status,
                'lan' => $params['keyspider_language'],
                'pla' => $params['keyspider_pla'],
                'liulanqi' => $params['keyspider_liulanqi'],
                'is_new' => $is_new,
                'pinci' => $pinci,
                'pid' => $first_record ? $first_record['id'] : 0,
                'keyspider_detail' => $params['keyspider_detail']
            ];
            $wpdb->insert($wpdb->prefix . 'keyspider_liuliang', $insert_data);

            if ($first_record) {
                $wpdb->update(
                    $wpdb->prefix . 'keyspider_liuliang',
                    ['shendu' => $pinci], // 总条数 = 当前pinci（已+1）
                    ['id' => $first_record['id']]
                );
            }
        }
        
    }
    public function keyspider_wztkjseo(){
       
        global $keyspider_wzt_log;
        if($keyspider_wzt_log){
            $keyspider_liuliang = get_option('keyspider_liuliang');
            if(isset($keyspider_liuliang['open']) && $keyspider_liuliang['open']){
                if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
                    $keyspider_ip = sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));
                }elseif(isset($_SERVER['REMOTE_ADDR'])){
                    $keyspider_ip = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR']));
                }else{
                    $keyspider_ip = '';
                }
                $keyspider_time = time();
                if(!isset($_SESSION['keyspider_liulan'])){
                    $_SESSION['keyspider_liulan'] = md5($keyspider_ip.wp_rand(1000000,999999));
                }
                
                ?>
                     <script>
                     function keyspider_getBrowserType() {
                        
                          // 获取浏览器 userAgent
                          var ua = navigator.userAgent
                          
                          // 是否为 Opera
                          var isOpera = ua.indexOf('Opera') > -1
                          // 返回结果
                          if (isOpera) { return 'Opera' }
                        
                          // 是否为 IE
                          var isIE = (ua.indexOf('compatible') > -1) && (ua.indexOf('MSIE') > -1) && !isOpera
                          var isIE11 = (ua.indexOf('Trident') > -1) && (ua.indexOf("rv:11.0") > -1)
                          // 返回结果
                          if (isIE11) { return 'IE11'
                          } else if (isIE) {
                            // 检测是否匹配
                            var re = new RegExp('MSIE (\\d+\\.\\d+);')
                            re.test(ua)
                            // 获取版本
                            var ver = parseFloat(RegExp["$1"])
                            // 返回结果
                            if (ver == 7) { return 'IE7'
                            } else if (ver == 8) { return 'IE8'
                            } else if (ver == 9) { return 'IE9'
                            } else if (ver == 10) { return 'IE10'
                            } else { return "IE" }
                          }
                        
                          // 是否为 Edge
                          var isEdge = ua.indexOf("Edge") > -1
                          // 返回结果
                          if (isEdge) { return 'Edge' }
                        
                          // 是否为 Firefox
                          var isFirefox = ua.indexOf("Firefox") > -1
                          // 返回结果
                          if (isFirefox) { return 'Firefox' }
                        
                          // 是否为 Safari
                          var isSafari = (ua.indexOf("Safari") > -1) && (ua.indexOf("Chrome") == -1)
                          // 返回结果
                          if (isSafari) { return "Safari" }
                        
                          // 是否为 Chrome
                          var isChrome = (ua.indexOf("Chrome") > -1) && (ua.indexOf("Safari") > -1) && (ua.indexOf("Edge") == -1)
                          // 返回结果
                          if (isChrome) { return 'Chrome' }
                        
                          // 是否为 UC
                          var isUC= ua.indexOf("UBrowser") > -1
                          // 返回结果
                          if (isUC) { return 'UC' }
                        
                          // 是否为 QQ
                          var isQQ= ua.indexOf("QQBrowser") > -1
                          // 返回结果
                          if (isUC) { return 'QQ' }
                        
                          // 都不是
                          return ''
                        }
                /**
 * 检测访客来源（带 30 天有效期）
 * - 自动识别付费 / 自然 / 外链 / 直接访问
 * - 首跳来源在 localStorage 中保存 30 天（插件专属键名，避免覆盖）
 * @param {string} [siteDomain=window.location.hostname] 当前站点主域名
 * @returns {{type: string, referrer: string|null, detail: string}}
 */
// 核心改造1：创建专属命名空间，隔离所有变量/函数，避免全局污染
window.KeySpider = window.KeySpider || {};

(function(ns) {
    // 插件专属配置：localStorage 键名添加前缀，避免与其他插件数据覆盖
    const STORAGE_KEY = 'keyspider_traffic_source';
    const EXPIRY_DAYS = 30;

    // 核心改造2：所有函数挂载到命名空间内，私有化，不暴露全局
    /**
     * 检测访客来源（私有化方法）
     */
    ns.detectTrafficSource = function(siteDomain = window.location.hostname) {
        const ref = document.referrer || '';
        const params = new URLSearchParams(window.location.search);
        const now = Date.now();

        // 已保存的首跳来源（如存在且未过期）
        const saved = localStorage.getItem(STORAGE_KEY);
        if (saved) {
            try {
                const parsed = JSON.parse(saved);
                if (parsed && parsed.type && parsed.detail && parsed.timestamp) {
                    const ageDays = (now - parsed.timestamp) / (1000 * 60 * 60 * 24);
                    if (ageDays < EXPIRY_DAYS) {
                        return parsed; // 未过期 → 直接返回
                    } else {
                        // 已过期 → 清除（仅删除当前插件的专属数据，不影响其他插件）
                        localStorage.removeItem(STORAGE_KEY);
                    }
                }
            } catch (e) {
                localStorage.removeItem(STORAGE_KEY);
                console.warn('KeySpider: localStorage 解析失败，已清除无效数据', e);
            }
        }

        const adParams = ['utm_medium', 'utm_source', 'utm_campaign', 'gclid', 'fbclid', 'ttclid', 'msclkid'];
        const searchEngines = [
            'google.', 'bing.', 'yahoo.', 'baidu.', 'sogou.', 'so.com',
            'duckduckgo.', 'yandex.', 'sm.cn', 'ecosia.'
        ];

        let traffic = {
            type: 'direct',
            referrer: null,
            detail: '直接访问',
            timestamp: now
        };

        // 1️⃣ 付费广告流量
        for (const p of adParams) {
            if (params.has(p)) {
                traffic = {
                    type: 'paid',
                    referrer: ref || null,
                    detail: '付费访问',
                    timestamp: now
                };
                break;
            }
        }

        // 2️⃣ 自然搜索流量
        if (traffic.type === 'direct' && ref) {
            const refLower = ref.toLowerCase();
            for (const engine of searchEngines) {
                if (refLower.includes(engine) || refLower.includes('/search?') || refLower.includes('query=')) {
                    traffic = {
                        type: 'organic',
                        referrer: ref,
                        detail: '自然流量',
                        timestamp: now
                    };
                    break;
                }
            }
        }

        // 3️⃣ 外部引荐流量
        if (traffic.type === 'direct' && ref && !ref.includes(siteDomain)) {
            traffic = {
                type: 'referral',
                referrer: ref,
                detail: '外部链接',
                timestamp: now
            };
        }

        // 4️⃣ 保存首跳来源（仅首次，保存插件专属数据）
        try {
            localStorage.setItem(STORAGE_KEY, JSON.stringify(traffic));
        } catch (e) {
            console.warn('KeySpider: localStorage 保存来源失败：', e);
        }

        return traffic;
    };

    /**
     * 获取操作系统信息（私有化方法）
     */
    ns.getKeyspiderOsInfo = function() {
        const userAgent = navigator.userAgent;
        if (userAgent.indexOf("Windows NT 10.0") !== -1) return "Windows 10";
        if (userAgent.indexOf("Windows NT 6.2") !== -1) return "Windows 8";
        if (userAgent.indexOf("Windows NT 6.1") !== -1) return "Windows 7";
        if (userAgent.indexOf("Windows NT 6.0") !== -1) return "Windows Vista";
        if (userAgent.indexOf("Windows NT 5.1") !== -1) return "Windows XP";
        if (userAgent.indexOf("Windows NT 5.0") !== -1) return "Windows 2000";
        if (userAgent.indexOf("Mac") !== -1) return "Mac/iOS";
        if (userAgent.indexOf("X11") !== -1) return "UNIX";
        if (userAgent.indexOf("Linux") !== -1) return "Linux";
        return "Other";
    };

    /**
     * 补充：缺失的浏览器类型检测方法（私有化，解决原代码引用报错问题）
     */
    ns.getKeyspiderBrowserType = function() {
        const userAgent = navigator.userAgent;
        let browser = "Other";
        
        if (/Chrome/i.test(userAgent) && !/Edge/i.test(userAgent)) {
            browser = "Chrome";
        } else if (/Firefox/i.test(userAgent)) {
            browser = "Firefox";
        } else if (/Microsoft Edge/i.test(userAgent) || /Edge/i.test(userAgent)) {
            browser = "Edge";
        } else if (/Safari/i.test(userAgent) && !/Chrome/i.test(userAgent)) {
            browser = "Safari";
        } else if (/Opera/i.test(userAgent) || /OPR/i.test(userAgent)) {
            browser = "Opera";
        } else if (/MSIE/i.test(userAgent) || /Trident/i.test(userAgent)) {
            browser = "IE";
        }
        
        return { browser: browser };
    };

    /**
     * 发送AJAX请求（私有化方法，规范参数编码）
     */
    ns.keyspider_sendRequest = function() {
        // 所有变量用 const/let 声明，避免隐性全局污染
        const keyspider_ip = '<?php echo esc_attr($keyspider_ip);?>';
        const keyspider_nonce = '<?php echo esc_attr(wp_create_nonce('keyspider'));?>';
        const keyspider_action = 'keyspider_liuliang_log';
        const keyspider_userAgent = navigator.userAgent;
        // 调用命名空间内的访客来源检测方法，获取最新数据
        const trafficData = ns.detectTrafficSource();
        const keyspider_referrer = document.referrer || "";
        const keyspider_currentUrl = window.location.href;
        const keyspider_allCookies = document.cookie;
        const keyspider_session = '<?php echo esc_attr(sanitize_text_field($_SESSION['keyspider_liulan']));?>';
        const keyspider_time = '<?php echo esc_attr($keyspider_time);?>';
        const keyspider_language = navigator.language || navigator.userLanguage;
        const keyspider_pla = ns.getKeyspiderOsInfo();
        const keyspider_liulanqi = ns.getKeyspiderBrowserType().browser;
        const keyspider_detail = trafficData.detail;
        const keyspider_type = /mobile/i.test(keyspider_userAgent) ? 2 : 1;

        // 初始化XHR对象
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '<?php echo esc_url(admin_url('admin-ajax.php')); ?>', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        // 可选：添加请求完成后的回调，便于调试
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status !== 200) {
                console.warn('KeySpider: 请求发送失败，状态码：', xhr.status);
            }
        };

        // 核心改造3：所有参数使用 encodeURIComponent 编码，避免特殊字符破坏请求结构
        const requestData = [
            'ip=' + encodeURIComponent(keyspider_ip),
            'userAgent=' + encodeURIComponent(keyspider_userAgent),
            'referrer=' + encodeURIComponent(keyspider_referrer),
            'currentUrl=' + encodeURIComponent(keyspider_currentUrl),
            'allCookies=' + encodeURIComponent(keyspider_allCookies),
            'nonce=' + encodeURIComponent(keyspider_nonce),
            'action=' + encodeURIComponent(keyspider_action),
            'keyspider_time=' + encodeURIComponent(keyspider_time),
            'session=' + encodeURIComponent(keyspider_session),
            'keyspider_type=' + encodeURIComponent(keyspider_type),
            'keyspider_language=' + encodeURIComponent(keyspider_language),
            'keyspider_pla=' + encodeURIComponent(keyspider_pla),
            'keyspider_liulanqi=' + encodeURIComponent(keyspider_liulanqi),
            'keyspider_detail=' + encodeURIComponent(keyspider_detail)
        ].join('&'); // 数组拼接更简洁，避免冗余的字符串连接

        // 发送规范化请求
        xhr.send(requestData);
    };

    // 核心改造4：保留定时请求逻辑，规范定时器参数，避免类型错误
    const requestInterval = <?php echo (int)$keyspider_liuliang['pinci'] * 1000; ?>; // 直接输出数字，避免字符串类型隐患

    // 1. 立即执行一次请求
    ns.keyspider_sendRequest();

    // 2. 定时重复执行请求（仅当间隔大于0时开启，避免无效定时器）
    if (requestInterval > 0) {
        ns.requestTimer = setInterval(ns.keyspider_sendRequest, requestInterval);
    }

})(window.KeySpider);
                 </script>
                 <?php   
            }
        }
    }

   
    public  function keyspider_addpages() {
        add_menu_page(__('蜘蛛/访客','key-spider'), __('蜘蛛/访客','key-spider'), 'manage_options', 'spider', [$this,'keyspider_toplevelpage'] );
    }
    public function keyspider_toplevelpage(){
        echo "<div id='keyspider_wztkj-app'></div>";
    }
    public  function keyspider_enqueue($hook){
        if( 'toplevel_page_spider' != $hook ) return;
        require plugin_dir_path( KEYSPIDER_FILE ) . 'inc/admin/assets.php';
        foreach($assets as $key=>$val){
            if($val['type']=='css'){
                 wp_enqueue_style( $val['name'],  plugin_dir_url( KEYSPIDER_FILE ).'inc/admin/'.$val['url'],false,KEYSPIDER_VERSION,'all');
            }elseif($val['type']=='js'){
                wp_enqueue_script( $val['name'], plugin_dir_url( KEYSPIDER_FILE ).'inc/admin/'.$val['url'], '', KEYSPIDER_VERSION, true);
            }
        }
        wp_register_script('spider.js', false, false, KEYSPIDER_VERSION,false);
        wp_enqueue_script('spider.js');
        $url1 = keyspider_common::keyspider_url(0);
      
        $key_spider_version  = esc_url_raw(admin_url('plugin-install.php?tab=plugin-information&plugin=key-spider'));
       
        wp_add_inline_script('spider.js', 'var keyspider_wztkj_url="'.esc_js(plugins_url('',KEYSPIDER_FILE)).'/inc/admin",keyspider_nonce="'. esc_attr(wp_create_nonce('keyspider')).'",keyspider_ajax="'.esc_url(admin_url('admin-ajax.php')).'",key_spider_version="'.esc_url_raw($key_spider_version).'",keyspider_url="'.esc_url($url1).'";', 'before');
    }
    public static function keyspider_get_token(){
        $keyspider_wzt_token1 = get_option('keyspider_wzt_token1');
        $keyspider_wzt_token2 = get_option('keyspider_wzt_token2');
        $keyspider_wzt_token3 = get_option('keyspider_wzt_token3');
        return [$keyspider_wzt_token1,$keyspider_wzt_token2,$keyspider_wzt_token3];
    }
    public function keyspider_dhdfkdksj($value){
        $arr = self::keyspider_get_token();
        $arr1 = apply_filters('keyspider_dssdd',2);
        $key= 0;
        foreach($arr as $k=>$v){
            
            if(keyspider_seo::keyspider_sanitizing_key($v,$arr1)){
                switch ($k) {
                    case 0:
                        $key = keyspider_seo::keyspider_sanitizing_date($v);
                        if($key){
                            break 2;
                        }else{
                            break;
                        }
                    case 1:
                        $key = keyspider_tag::keyspider_sanitizing_date($v);
                        if($key){
                            break 2;
                        }else{
                            break;
                        }
                    case 2:
                        $key = keyspider_zhizhu::keyspider_sanitizing_date($v);
                        if($key){
                            break 2;
                        }else{
                            break;
                        }
                   
                }
            }
        }
        return $key;
    }
     public function keyspider_dssdd($value){
        global $keyspider_wzt_log;
        $url = keyspider_common::keyspider_url(0);
        $log = $keyspider_wzt_log;
        $type = 4;
        $arr = [
            md5($url),
            md5($log),
            md5($type),
            md5($url.$log),
            md5($url.$type),
            md5($log.$url),
            md5($log.$type),
            md5($type.$url),
            md5($type.$log),
            md5($url.$log.$type),
            md5($url.$type.$log),
            md5($log.$url.$type),
            md5($log.$type.$url),
            md5($type.$url.$log),
            md5($type.$log.$url),
        ];
        return $arr;
    }
    public  function spider_plugin_action_links ( $links) {
        $links[] = '<a href="' . admin_url( 'admin.php?page=spider&nonce='.esc_attr(wp_create_nonce('keyspider')) ) . '">设置</a>';
        return $links;
    }

    public static function keyspider_url($type=0){
        if($type==1){
            $url1 = get_option('siteurl');
            $url1 = wp_parse_url($url1);
            $url1 = $url1['scheme'].'://'.$url1['host'];
            return $url1;
        }else{
            $url1 = get_option('siteurl');
            $url1 = str_replace('https://','',$url1);
            $url1 = str_replace('http://','',$url1);
            $url1 = trim($url1,'/');
            $url1 = explode('/',$url1);
            return $url1[0];
        }
    }
    public static function  get_jifen(){
        $url = 'https://api.seoceo.cn/api/kp/jifen?url='.self::keyspider_url(0);
        $defaults = array(
            'timeout' => 4000,
            'connecttimeout'=>4000,
            'redirection' => 3,
            'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
            'sslverify' => FALSE,
        );
        $result = wp_remote_get($url,$defaults);
        
        if(!is_wp_error($result)){
            $jifen = wp_remote_retrieve_body($result);
            
            $jifen =$jifen?$jifen:0;
        }else{
            $jifen = 0;
        }
        return $jifen;
    }
   
}
?>