Changeset 3625549
- Timestamp:
- 07/28/2026 07:41:53 AM (3 months ago)
- Location:
- baiduseo
- Files:
-
- 64 added
- 1 deleted
- 8 edited
-
tags/2.2.2 (added)
-
tags/2.2.2/inc (added)
-
tags/2.2.2/inc/admin (added)
-
tags/2.2.2/inc/admin/assets (added)
-
tags/2.2.2/inc/admin/assets.php (added)
-
tags/2.2.2/inc/admin/assets/baiduseo-post-tag-recommend.js (added)
-
tags/2.2.2/inc/admin/assets/baolu-5T1L3U4A.png (added)
-
tags/2.2.2/inc/admin/assets/bootBg-Lr_BxKhx.png (added)
-
tags/2.2.2/inc/admin/assets/chsit1-Yi-xLlvg.png (added)
-
tags/2.2.2/inc/admin/assets/chsit2-t344QQvR.png (added)
-
tags/2.2.2/inc/admin/assets/chsit3-Tg603MZl.png (added)
-
tags/2.2.2/inc/admin/assets/chsit4-eQRRH9if.png (added)
-
tags/2.2.2/inc/admin/assets/hide_list-9ybXf38e.png (added)
-
tags/2.2.2/inc/admin/assets/home-1-BnDt_i1L.png (added)
-
tags/2.2.2/inc/admin/assets/home-10-2Ow9oOlT.png (added)
-
tags/2.2.2/inc/admin/assets/home-11-DVFl4P7O.png (added)
-
tags/2.2.2/inc/admin/assets/home-12-bajtJoTB.png (added)
-
tags/2.2.2/inc/admin/assets/home-13-ew_dHx5g.png (added)
-
tags/2.2.2/inc/admin/assets/home-14-CQxgr_DP.png (added)
-
tags/2.2.2/inc/admin/assets/home-15-Z2pMJ_7I.png (added)
-
tags/2.2.2/inc/admin/assets/home-2-rowHHTw2.png (added)
-
tags/2.2.2/inc/admin/assets/home-3-P1LHb7C4.png (added)
-
tags/2.2.2/inc/admin/assets/home-4-S83kirr0.png (added)
-
tags/2.2.2/inc/admin/assets/home-5-1TMe-rwY.png (added)
-
tags/2.2.2/inc/admin/assets/home-6-4wsZARBy.png (added)
-
tags/2.2.2/inc/admin/assets/home-7-jd38O8Wu.png (added)
-
tags/2.2.2/inc/admin/assets/home-8-E7Ma32xd.png (added)
-
tags/2.2.2/inc/admin/assets/home-9-wNvgk2nT.png (added)
-
tags/2.2.2/inc/admin/assets/home-bg-6miY6DYV.png (added)
-
tags/2.2.2/inc/admin/assets/icon_record-PJ8sHm0l.png (added)
-
tags/2.2.2/inc/admin/assets/icon_record_active-AOt5asqN.png (added)
-
tags/2.2.2/inc/admin/assets/index.js (added)
-
tags/2.2.2/inc/admin/assets/jfcz-DSLLUEoN.png (added)
-
tags/2.2.2/inc/admin/assets/logo-qPh-VmHa.png (added)
-
tags/2.2.2/inc/admin/assets/seojckzt-mtk1ACVx.png (added)
-
tags/2.2.2/inc/admin/assets/tanchuceng-bg-cQtiDd5L.png (added)
-
tags/2.2.2/inc/admin/assets/wenzhang-EW_5s7vy.png (added)
-
tags/2.2.2/inc/admin/assets/wztdy--yFIfPsT.jpg (added)
-
tags/2.2.2/inc/admin/assets/wztkj_kj02-_YIwjW5o.png (added)
-
tags/2.2.2/inc/admin/assets/yq_bd-eYDRGHX9.png (added)
-
tags/2.2.2/inc/admin/assets/yq_by-uu5J2bmv.png (added)
-
tags/2.2.2/inc/admin/assets/yq_gg-_zHz-4PT.png (added)
-
tags/2.2.2/inc/admin/cron.php (added)
-
tags/2.2.2/inc/admin/cron_tongbu.php (added)
-
tags/2.2.2/inc/admin/cron_ts.php (added)
-
tags/2.2.2/inc/admin/cron_zhizhu.php (added)
-
tags/2.2.2/inc/admin/get.php (added)
-
tags/2.2.2/inc/admin/kp.php (added)
-
tags/2.2.2/inc/admin/post.php (added)
-
tags/2.2.2/inc/admin/seo.php (added)
-
tags/2.2.2/inc/admin/set.php (added)
-
tags/2.2.2/inc/admin/tag.php (added)
-
tags/2.2.2/inc/admin/txt (added)
-
tags/2.2.2/inc/admin/txt/baiduseo_zhizhu_log.txt (added)
-
tags/2.2.2/inc/admin/zhizhu.php (added)
-
tags/2.2.2/inc/admin/zz.php (added)
-
tags/2.2.2/inc/common (added)
-
tags/2.2.2/inc/common/index.php (added)
-
tags/2.2.2/inc/index (added)
-
tags/2.2.2/inc/index/youhua.php (added)
-
tags/2.2.2/readme.txt (added)
-
tags/2.2.2/seo_title_baidu.php (added)
-
trunk/inc/admin/assets.php (modified) (1 diff)
-
trunk/inc/admin/assets/baiduseo-post-tag-recommend.js (added)
-
trunk/inc/admin/assets/index-pmcy0olr.js (deleted)
-
trunk/inc/admin/assets/index.js (added)
-
trunk/inc/admin/get.php (modified) (10 diffs)
-
trunk/inc/admin/post.php (modified) (13 diffs)
-
trunk/inc/admin/seo.php (modified) (1 diff)
-
trunk/inc/admin/zhizhu.php (modified) (4 diffs)
-
trunk/inc/common/index.php (modified) (7 diffs)
-
trunk/readme.txt (modified) (4 diffs)
-
trunk/seo_title_baidu.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
baiduseo/trunk/inc/admin/assets.php
r3497150 r3625549 5 5 'name'=>'tagmanage_css_3', 6 6 'type'=>'js', 7 'url'=>'./assets/index -pmcy0olr.js',7 'url'=>'./assets/index.js', 8 8 9 9 ], -
baiduseo/trunk/inc/admin/get.php
r3497150 r3625549 13 13 add_action('wp_ajax_baiduseo_get_cate_seo', [$this,'baiduseo_get_cate_seo']); 14 14 add_action('wp_ajax_baiduseo_get_page_seo', [$this,'baiduseo_get_page_seo']); 15 add_action('wp_ajax_baiduseo_get_geo', [$this,'baiduseo_get_geo']); 15 16 add_action('wp_ajax_baiduseo_get_wyc', [$this,'baiduseo_get_wyc']); 16 17 add_action('wp_ajax_baiduseo_get_yuanchuang', [$this,'yuanchuang']); … … 50 51 add_action('wp_ajax_baiduseo_get_liuliang_sl', [$this,'baiduseo_get_liuliang_sl']); 51 52 add_action('wp_ajax_baiduseo_get_liuliang_list', [$this,'baiduseo_get_liuliang_list']); 53 add_action('wp_ajax_baiduseo_liuliang_export', [$this,'baiduseo_liuliang_export']); 54 add_action('wp_ajax_baiduseo_fix_ai_source', [$this,'baiduseo_fix_ai_source']); 52 55 add_action('wp_ajax_baiduseo_get_vip', [$this,'baiduseo_get_vip']); 53 56 add_action('wp_ajax_baiduseo_get_301', [$this,'baiduseo_get_301']); … … 86 89 } 87 90 } 91 } 92 private function baiduseo_llms_default_form(){ 93 return [ 94 'siteName'=>get_option('blogname'), 95 'language'=>'zh-CN', 96 'sitemapUrl'=>trim(get_option('home'),'/').'/sitemap.xml', 97 'siteIntro'=>get_option('blogdescription'), 98 'businessScope'=>'', 99 'targetUsers'=>'', 100 'serviceArea'=>'', 101 ]; 102 } 103 private function baiduseo_llms_saved_map($items){ 104 $map = []; 105 if(!is_array($items)){ 106 return $map; 107 } 108 foreach($items as $item){ 109 if(is_array($item) && isset($item['id'])){ 110 $map[(string)$item['id']] = $item; 111 } 112 } 113 return $map; 114 } 115 private function baiduseo_llms_merge_entries($entries,$saved_items){ 116 $saved_map = $this->baiduseo_llms_saved_map($saved_items); 117 foreach($entries as $key=>$entry){ 118 $entry_id = isset($entry['id']) ? (string)$entry['id'] : ''; 119 if($entry_id !== '' && isset($saved_map[$entry_id])){ 120 if(array_key_exists('checked',$saved_map[$entry_id])){ 121 $entries[$key]['checked'] = (bool)$saved_map[$entry_id]['checked']; 122 } 123 if(array_key_exists('desc',$saved_map[$entry_id])){ 124 $entries[$key]['desc'] = $saved_map[$entry_id]['desc']; 125 } 126 } 127 } 128 return $entries; 129 } 130 private function baiduseo_llms_excerpt($content){ 131 $content = wp_strip_all_tags((string)$content); 132 $content = trim(preg_replace('/\s+/u',' ',$content)); 133 if(function_exists('mb_substr')){ 134 return mb_substr($content,0,120); 135 } 136 return substr($content,0,120); 137 } 138 private function baiduseo_llms_posts($post_type){ 139 $posts = get_posts([ 140 'post_type'=>$post_type, 141 'post_status'=>'publish', 142 'numberposts'=>-1, 143 'orderby'=>$post_type === 'page' ? 'menu_order title' : 'date', 144 'order'=>$post_type === 'page' ? 'ASC' : 'DESC', 145 ]); 146 $data = []; 147 foreach($posts as $post){ 148 $desc = $post->post_excerpt ? $this->baiduseo_llms_excerpt($post->post_excerpt) : ''; 149 $data[] = [ 150 'id'=>(int)$post->ID, 151 'title'=>get_the_title($post), 152 'url'=>get_permalink($post), 153 'desc'=>$desc, 154 'checked'=>true, 155 ]; 156 } 157 return $data; 158 } 159 private function baiduseo_llms_categories(){ 160 $categories = get_categories(['hide_empty'=>false]); 161 $data = []; 162 foreach($categories as $category){ 163 $category_link = get_category_link($category->term_id); 164 $data[] = [ 165 'id'=>(int)$category->term_id, 166 'title'=>$category->name, 167 'url'=>is_wp_error($category_link) ? '' : $category_link, 168 'desc'=>$this->baiduseo_llms_excerpt($category->description), 169 'checked'=>true, 170 ]; 171 } 172 return $data; 173 } 174 private function baiduseo_llms_builder(){ 175 $saved = get_option('seo_llms_builder'); 176 if(!is_array($saved)){ 177 $saved = []; 178 } 179 $saved_form = isset($saved['form']) && is_array($saved['form']) ? $saved['form'] : []; 180 $builder = [ 181 'form'=>array_merge($this->baiduseo_llms_default_form(),$saved_form), 182 'pages'=>$this->baiduseo_llms_merge_entries($this->baiduseo_llms_posts('page'),isset($saved['pages']) ? $saved['pages'] : []), 183 'posts'=>$this->baiduseo_llms_merge_entries($this->baiduseo_llms_posts('post'),isset($saved['posts']) ? $saved['posts'] : []), 184 'categories'=>$this->baiduseo_llms_merge_entries($this->baiduseo_llms_categories(),isset($saved['categories']) ? $saved['categories'] : []), 185 'manualLinks'=>isset($saved['manualLinks']) && is_array($saved['manualLinks']) ? $saved['manualLinks'] : [], 186 'entryGroups'=>isset($saved['entryGroups']) && is_array($saved['entryGroups']) ? $saved['entryGroups'] : [], 187 'customModules'=>isset($saved['customModules']) && is_array($saved['customModules']) ? $saved['customModules'] : [], 188 ]; 189 return $builder; 88 190 } 89 191 public function baiduseo_get_beian(){ … … 603 705 }elseif(isset($_POST['source']) && (int)$_POST['source']==4){ 604 706 $sql .= ' and baiduseo_detail="自然流量"'; 707 }elseif(isset($_POST['source']) && (int)$_POST['source']==5){ 708 $sql .= ' and baiduseo_detail="AI来源"'; 605 709 } 606 710 if(isset($_POST['type']) && (int)$_POST['type']==1){ … … 619 723 $sql .= ' order by id desc limit %d,35 '; 620 724 if(empty($con1)){ 725 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are selected from fixed branches with no user placeholders in this branch. 621 726 $count = $wpdb->query($sql1,ARRAY_A); 622 727 }else{ 728 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are selected from fixed branches; user values are prepared via placeholders. 623 729 $count = $wpdb->query($wpdb->prepare($sql1,array_values($con1)),ARRAY_A); 624 730 } 625 731 732 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are selected from fixed branches; user values are prepared via placeholders. 626 733 $list = $wpdb->get_results($wpdb->prepare($sql,array_values($con)),ARRAY_A); 627 734 … … 678 785 679 786 787 } 788 public function baiduseo_fix_ai_source(){ 789 $this->check_permission('manage_options'); 790 global $wpdb; 791 792 $table = $wpdb->prefix . 'baiduseo_liuliang'; 793 $ai_sources = [ 794 'chatgpt.com', 795 'chat.openai.com', 796 'openai.com', 797 'perplexity.ai', 798 'pplx.ai', 799 'claude.ai', 800 'poe.com', 801 'you.com', 802 'gemini.google.com', 803 'bard.google.com', 804 'copilot.microsoft.com', 805 'bing.com/chat', 806 'metaso.cn', 807 'kimi.moonshot.cn', 808 'kimi.com', 809 'doubao.com', 810 'link.wttur.cn', 811 'yuanbao.tencent.com', 812 'ima.qq.com', 813 'tongyi.aliyun.com', 814 'qianwen.aliyun.com', 815 'yiyan.baidu.com', 816 'chat.baidu.com', 817 'deepseek.com', 818 'deepseek.ai', 819 'chatglm.cn', 820 'zhipuai.cn', 821 'coze.cn', 822 'grok.com', 823 'x.ai' 824 ]; 825 826 $like_sql = []; 827 $like_args = []; 828 foreach ($ai_sources as $source) { 829 $like = '%' . $wpdb->esc_like($source) . '%'; 830 $like_sql[] = '(source LIKE %s OR url LIKE %s)'; 831 $like_args[] = $like; 832 $like_args[] = $like; 833 } 834 835 if (empty($like_sql)) { 836 echo wp_json_encode(['code'=>1,'count'=>0,'msg'=>'没有可修正的数据']);exit; 837 } 838 839 $source_where = '(' . implode(' OR ', $like_sql) . ')'; 840 $detail_where = "(baiduseo_detail IS NULL OR baiduseo_detail = '' OR baiduseo_detail = '直接访问' OR baiduseo_detail = '外部链接')"; 841 $child_source_where = str_replace(['source LIKE', 'url LIKE'], ['child.source LIKE', 'child.url LIKE'], $source_where); 842 $child_detail_where = str_replace('baiduseo_detail', 'child.baiduseo_detail', $detail_where); 843 844 $child_sql = " 845 UPDATE {$table} child 846 INNER JOIN {$table} parent ON child.pid = parent.id 847 SET parent.baiduseo_detail = 'AI来源' 848 WHERE child.pid > 0 849 AND (parent.baiduseo_detail IS NULL OR parent.baiduseo_detail = '' OR parent.baiduseo_detail = '直接访问' OR parent.baiduseo_detail = '外部链接') 850 AND (child.baiduseo_detail = 'AI来源' OR ({$child_detail_where} AND {$child_source_where})) 851 "; 852 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL is built from a hard-coded AI source list; LIKE values are prepared below. 853 $parent_count = (int)$wpdb->query($wpdb->prepare($child_sql, $like_args)); 854 855 $row_sql = " 856 UPDATE {$table} 857 SET baiduseo_detail = 'AI来源' 858 WHERE {$detail_where} 859 AND {$source_where} 860 "; 861 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL is built from a hard-coded AI source list; LIKE values are prepared below. 862 $row_count = (int)$wpdb->query($wpdb->prepare($row_sql, $like_args)); 863 $total = $parent_count + $row_count; 864 865 echo wp_json_encode(['code'=>1,'count'=>$total,'parent_count'=>$parent_count,'row_count'=>$row_count,'msg'=>'AI来源修正完成']);exit; 866 } 867 public function baiduseo_liuliang_export(){ 868 $this->check_permission('manage_options'); 869 global $wpdb; 870 $con = []; 871 $sql ='select * from '.$wpdb->prefix . 'baiduseo_liuliang where status=1'; 872 if(!isset($_POST['fangke'])){ 873 $_POST['fangke'] =1; 874 } 875 if(!isset($_POST['pinci'])){ 876 $_POST['pinci'] =1; 877 } 878 if(!isset($_POST['shendu'])){ 879 $_POST['shendu'] =1; 880 } 881 if(!isset($_POST['shichang'])){ 882 $_POST['shichang'] =1; 883 } 884 if(!isset($_POST['time'])){ 885 $_POST['time'] =0; 886 } 887 if((int)$_POST['fangke']==1){ 888 $sql .= ' and is_new=1'; 889 }elseif((int)$_POST['fangke']==2){ 890 $sql .= ' and is_new=0'; 891 } 892 if((int)$_POST['pinci']==1){ 893 $sql .= ' and pinci=1'; 894 }elseif((int)$_POST['pinci']==2){ 895 $sql .= ' and pinci=2'; 896 }elseif((int)$_POST['pinci']==3){ 897 $sql .= ' and pinci=3'; 898 }elseif((int)$_POST['pinci']==4){ 899 $sql .= ' and pinci=4'; 900 }elseif((int)$_POST['pinci']==5){ 901 $sql .= ' and pinci>=5 and pinci<=10'; 902 }elseif((int)$_POST['pinci']==6){ 903 $sql .= ' and pinci>=11 and pinci<=20'; 904 }elseif((int)$_POST['pinci']==7){ 905 $sql .= ' and pinci>20'; 906 } 907 if((int)$_POST['shendu']==1){ 908 $sql .= ' and shendu=1'; 909 }elseif((int)$_POST['shendu']==2){ 910 $sql .= ' and shendu=2'; 911 }elseif((int)$_POST['shendu']==3){ 912 $sql .= ' and shendu=3'; 913 }elseif((int)$_POST['shendu']==4){ 914 $sql .= ' and shendu=4'; 915 }elseif((int)$_POST['shendu']==5){ 916 $sql .= ' and shendu>=5 and shendu<=10'; 917 }elseif((int)$_POST['shendu']==6){ 918 $sql .= ' and shendu>=11 and shendu<=20'; 919 }elseif((int)$_POST['shendu']==7){ 920 $sql .= ' and shendu>20'; 921 } 922 if((int)$_POST['shichang']==1){ 923 $sql .= ' and shichang<=30'; 924 }elseif((int)$_POST['shichang']==2){ 925 $sql .= ' and shichang>30 and shichang<=60'; 926 }elseif((int)$_POST['shichang']==3){ 927 $sql .= ' and shichang>60 and shichang<=90'; 928 }elseif((int)$_POST['shichang']==4){ 929 $sql .= ' and shichang>90 and shichang<=180'; 930 }elseif((int)$_POST['shichang']==5){ 931 $sql .= ' and shichang>180 and shichang<=300'; 932 }elseif((int)$_POST['shichang']==6){ 933 $sql .= ' and shichang>300 and shichang<=600'; 934 }elseif((int)$_POST['shichang']==7){ 935 $sql .= ' and shichang>600'; 936 } 937 if(sanitize_text_field(wp_unslash($_POST['time']))){ 938 $time = sanitize_text_field(wp_unslash($_POST['time'])); 939 $timezone_offet = get_option( 'gmt_offset'); 940 $sta1 = strtotime($time)-$timezone_offet*3600; 941 $end1 = strtotime($time)+24*3600-$timezone_offet*3600; 942 $sql .=' and unix_timestamp(time)>%d and unix_timestamp(time)<%d'; 943 $con = [$sta1,$end1]; 944 } 945 if(isset($_POST['rukou']) && sanitize_text_field(wp_unslash($_POST['rukou']))){ 946 $rukou = sanitize_text_field(wp_unslash($_POST['rukou'])); 947 $sql .= ' and url=%s'; 948 $con[] = $rukou; 949 } 950 if(isset($_POST['ip']) && sanitize_text_field(wp_unslash($_POST['ip']))){ 951 $ip = sanitize_text_field(wp_unslash($_POST['ip'])); 952 $sql .= ' and ip=%s'; 953 $con[] = $ip; 954 } 955 if(isset($_POST['session']) && sanitize_text_field(wp_unslash($_POST['session']))){ 956 $session = sanitize_text_field(wp_unslash($_POST['session'])); 957 $sql .= ' and session=%s'; 958 $con[] = $session; 959 } 960 if(isset($_POST['source']) && (int)$_POST['source']==1){ 961 $sql .= ' and baiduseo_detail="直接访问"'; 962 }elseif(isset($_POST['source']) && (int)$_POST['source']==2){ 963 $sql .= ' and baiduseo_detail="付费访问"'; 964 }elseif(isset($_POST['source']) && (int)$_POST['source']==3){ 965 $sql .= ' and baiduseo_detail="外部链接"'; 966 }elseif(isset($_POST['source']) && (int)$_POST['source']==4){ 967 $sql .= ' and baiduseo_detail="自然流量"'; 968 }elseif(isset($_POST['source']) && (int)$_POST['source']==5){ 969 $sql .= ' and baiduseo_detail="AI来源"'; 970 } 971 if(isset($_POST['type']) && (int)$_POST['type']==1){ 972 $sql .= ' and type=1'; 973 }elseif(isset($_POST['type']) && (int)$_POST['type']==2){ 974 $sql .= ' and type=2'; 975 } 976 $sql .= ' order by id desc'; 977 if(empty($con)){ 978 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are selected from fixed branches with no user placeholders in this branch. 979 $list = $wpdb->get_results($sql,ARRAY_A); 980 }else{ 981 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are selected from fixed branches; user values are prepared via placeholders. 982 $list = $wpdb->get_results($wpdb->prepare($sql,array_values($con)),ARRAY_A); 983 } 984 985 $filename = '访客报表_' . current_time('Ymd_His') . '.csv'; 986 header('Content-Type: text/csv; charset=UTF-8'); 987 header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"; filename*=UTF-8\'\'' . rawurlencode($filename)); 988 header('Pragma: no-cache'); 989 header('Expires: 0'); 990 echo "\xEF\xBB\xBF"; 991 $output = fopen('php://output', 'w'); 992 $csv_safe = function($value){ 993 if(!is_scalar($value)){ 994 return ''; 995 } 996 $value = (string)$value; 997 return preg_match('/^[=+\-@]/', $value) ? "'" . $value : $value; 998 }; 999 $format_duration = function($value){ 1000 $seconds = (int)$value; 1001 if($seconds >= 60){ 1002 $minutes = floor($seconds / 60); 1003 $remaining_seconds = $seconds % 60; 1004 return $minutes . "'" . ($remaining_seconds ? $remaining_seconds . '"' : ''); 1005 } 1006 return $seconds . '"'; 1007 }; 1008 fputcsv($output, ['序号','首次访问','最后访问','地域','首次访问来源','入口页面','访问IP','访问时长','访问页数','访客类型','访客识别码','上一次访问时间','本次来源','最后停留在','操作系统','语言环境','浏览器','访问频次','访问路径']); 1009 $export_count = count($list); 1010 foreach($list as $index=>$val){ 1011 $newlao = $wpdb->get_results($wpdb->prepare('select * from '.$wpdb->prefix . 'baiduseo_liuliang where session=%s and status=1 and id<%d order by id desc limit 1',$val['session'],$val['id']),ARRAY_A); 1012 $lujing = $wpdb->get_results($wpdb->prepare('select * from '.$wpdb->prefix . 'baiduseo_liuliang where pid=%d or id=%d order by id asc',$val['id'],$val['id']),ARRAY_A); 1013 $last_time = ''; 1014 $end_url = isset($val['url']) ? $val['url'] : ''; 1015 $path_urls = []; 1016 $totaltime = 1; 1017 if(isset($val['updatetime']) && $val['updatetime']){ 1018 $totaltime = strtotime($val['updatetime'])-strtotime($val['time']); 1019 } 1020 if(!empty($lujing)){ 1021 foreach($lujing as $v){ 1022 $last_time = isset($v['time']) ? $v['time'] : $last_time; 1023 $end_url = isset($v['url']) ? $v['url'] : $end_url; 1024 if(isset($v['url']) && $v['url']){ 1025 $path_urls[] = $v['url']; 1026 } 1027 if(isset($v['shichang']) && $v['shichang']){ 1028 $totaltime += (int)$v['shichang']; 1029 }elseif(isset($v['updatetime']) && $v['updatetime']){ 1030 $totaltime += strtotime($v['updatetime'])-strtotime($v['time']); 1031 }else{ 1032 $totaltime += 1; 1033 } 1034 } 1035 } 1036 $total_page = $wpdb->query($wpdb->prepare('select * from '.$wpdb->prefix . 'baiduseo_liuliang where pid=%d',$val['id']),ARRAY_A)+1; 1037 $visitor_type = isset($val['is_new']) && (int)$val['is_new'] === 0 ? '新访客' : '旧访客'; 1038 $source_detail = isset($val['baiduseo_detail']) && $val['baiduseo_detail'] ? $val['baiduseo_detail'] : '直接访问'; 1039 $duration = isset($val['shichang']) && $val['shichang'] ? $val['shichang'] : $totaltime; 1040 $row = [ 1041 $export_count - $index, 1042 isset($val['time']) ? $val['time'] : '', 1043 count($lujing)>1 ? $last_time : '', 1044 isset($val['sheng']) ? $val['sheng'] : '', 1045 $source_detail, 1046 isset($val['url']) ? $val['url'] : '', 1047 isset($val['ip']) ? $val['ip'] : '', 1048 $format_duration($duration), 1049 $total_page, 1050 $visitor_type, 1051 isset($val['session']) ? $val['session'] : '', 1052 !empty($newlao) && isset($newlao[0]['time']) ? $newlao[0]['time'] : '', 1053 $source_detail, 1054 $end_url, 1055 isset($val['pla']) ? $val['pla'] : '', 1056 isset($val['lan']) ? $val['lan'] : '', 1057 isset($val['liulanqi']) ? $val['liulanqi'] : '', 1058 isset($val['pinci']) ? $val['pinci'] : '', 1059 implode(' -> ', $path_urls) 1060 ]; 1061 fputcsv($output, array_map($csv_safe, $row)); 1062 } 1063 exit; 680 1064 } 681 1065 public function baiduseo_get_liuliang_sl(){ … … 1678 2062 $this->check_permission('manage_options'); 1679 2063 $page=isset($_POST['page'])?(int)$_POST['page']:0; 1680 $baiduseo_page = get_post_meta( $page, 'baiduseo_page', true ); 2064 if($page && $page === (int)get_option('page_on_front')){ 2065 $baiduseo_page = get_option('seo_init'); 2066 }else{ 2067 $baiduseo_page = get_post_meta( $page, 'baiduseo_page', true ); 2068 } 1681 2069 echo wp_json_encode(['code'=>1,'data'=>$baiduseo_page]);exit; 1682 2070 1683 2071 } 1684 2072 public function baiduseo_get_cate_seo(){ … … 1687 2075 $seo_init = get_option('baiduseo_cate_'.$cate); 1688 2076 echo wp_json_encode(['code'=>1,'data'=>$seo_init]);exit; 2077 2078 } 2079 private function baiduseo_get_geo_image($post_id){ 2080 $image = get_the_post_thumbnail_url($post_id, 'full'); 2081 return $image ? $image : ''; 2082 } 2083 private function baiduseo_geo_default_form(){ 2084 return [ 2085 'pageType'=>'', 2086 'pageUrl'=>'', 2087 'seoTitle'=>'', 2088 'seoKeywords'=>'', 2089 'seoDesc'=>'', 2090 'shareImage'=>'', 2091 'shareImageId'=>'', 2092 'ogImage'=>'', 2093 'ogImageId'=>'', 2094 'twitterImage'=>'', 2095 'twitterImageId'=>'', 2096 'schemaType'=>'OrganizationWebSite', 2097 'companyName'=>'', 2098 'companyAddress'=>'', 2099 'phone'=>'', 2100 'email'=>'', 2101 'author'=>'', 2102 'published'=>'', 2103 'modified'=>'', 2104 'serviceName'=>'', 2105 'areaServed'=>'', 2106 'faqText'=>'', 2107 'customSchemaJson'=>'', 2108 'wechat'=>'', 2109 'weibo'=>'', 2110 'zhihu'=>'', 2111 'bili'=>'', 2112 'xurl'=>'', 2113 'linkedin'=>'', 2114 'facebook'=>'', 2115 'youtube'=>'', 2116 'baiduVerify'=>'', 2117 'bingVerify'=>'', 2118 'soVerify'=>'', 2119 'sogouVerify'=>'', 2120 'shenmaVerify'=>'' 2121 ]; 2122 } 2123 private function baiduseo_geo_source_form_keys(){ 2124 return ['pageType','pageUrl','seoTitle','seoKeywords','seoDesc','shareImage','shareImageId','author','published','modified']; 2125 } 2126 private function baiduseo_geo_schema_source_form_map(){ 2127 return [ 2128 'title'=>'seoTitle', 2129 'desc'=>'seoDesc', 2130 'url'=>'pageUrl', 2131 'image'=>'shareImage', 2132 'author'=>'author', 2133 'published'=>'published', 2134 'modified'=>'modified' 2135 ]; 2136 } 2137 private function baiduseo_geo_filter_saved_form($form){ 2138 if(!is_array($form)) return []; 2139 return $form; 2140 } 2141 private function baiduseo_geo_apply_manual_source_form($form, $saved_form, $schema_source){ 2142 if(!is_array($schema_source)) return $form; 2143 foreach($this->baiduseo_geo_schema_source_form_map() as $source_key=>$form_key){ 2144 if(isset($schema_source[$source_key]) && $schema_source[$source_key] === 'manual'){ 2145 $form[$form_key] = isset($saved_form[$form_key]) ? $saved_form[$form_key] : ''; 2146 if($source_key === 'image'){ 2147 $form['shareImageId'] = isset($saved_form['shareImageId']) ? $saved_form['shareImageId'] : ''; 2148 } 2149 } 2150 } 2151 return $form; 2152 } 2153 private function baiduseo_geo_verify_content($value){ 2154 $value = trim((string)$value); 2155 if($value === '') return ''; 2156 $value = sanitize_text_field(html_entity_decode($value, ENT_QUOTES, get_bloginfo('charset'))); 2157 if($value === '' || strlen($value) > 256) return ''; 2158 if(!preg_match('/^[A-Za-z0-9._:-]+$/', $value)) return ''; 2159 return $value; 2160 } 2161 private function baiduseo_geo_webmaster_verify_form(){ 2162 $baiduseo_zz = baiduseo_set::baiduseo_get_option(baiduseo_kp::baiduseo_wzt_log(), 'baiduseo_zz'); 2163 if(empty($baiduseo_zz)) $baiduseo_zz = get_option('baiduseo_zz'); 2164 if(!is_array($baiduseo_zz)) return []; 2165 $form = []; 2166 $zz_link = isset($baiduseo_zz['zz_link']) ? trim((string)$baiduseo_zz['zz_link']) : ''; 2167 $baidu_token = ''; 2168 if($zz_link !== ''){ 2169 $query = wp_parse_url(str_replace('&', '&', $zz_link), PHP_URL_QUERY); 2170 if($query){ 2171 parse_str($query, $params); 2172 $baidu_token = isset($params['token']) ? $this->baiduseo_geo_verify_content($params['token']) : ''; 2173 } 2174 } 2175 $form['baiduVerify'] = $baidu_token; 2176 $form['bingVerify'] = isset($baiduseo_zz['bing_key']) ? $this->baiduseo_geo_verify_content($baiduseo_zz['bing_key']) : ''; 2177 return $form; 2178 } 2179 private function baiduseo_geo_home_form(){ 2180 $seo = get_option('seo_init'); 2181 $front_page_id = (int)get_option('page_on_front'); 2182 $title = get_bloginfo('name'); 2183 $keywords = is_array($seo) && isset($seo['keywords']) ? $seo['keywords'] : ''; 2184 $description = is_array($seo) && isset($seo['description']) ? $seo['description'] : ''; 2185 $image = ''; 2186 $author = ''; 2187 $published = ''; 2188 $modified = ''; 2189 if($front_page_id){ 2190 $front_page = get_post($front_page_id); 2191 if($front_page && $front_page->post_type === 'page'){ 2192 $title = get_post_field('post_title', $front_page_id, 'raw'); 2193 $image = $this->baiduseo_get_geo_image($front_page_id); 2194 $author = get_the_author_meta('display_name', $front_page->post_author); 2195 $published = get_the_date('c', $front_page_id); 2196 $modified = get_the_modified_date('c', $front_page_id); 2197 } 2198 } 2199 if(!$image){ 2200 $custom_logo_id = get_theme_mod('custom_logo'); 2201 if($custom_logo_id){ 2202 $image = wp_get_attachment_image_url($custom_logo_id, 'full'); 2203 } 2204 } 2205 return [ 2206 'pageType'=>'website', 2207 'pageUrl'=>home_url('/'), 2208 'seoTitle'=>$title ? $title : '', 2209 'seoKeywords'=>$keywords ? $keywords : '', 2210 'seoDesc'=>$description ? $description : '', 2211 'shareImage'=>$image ? $image : '', 2212 'author'=>$author ? $author : '', 2213 'published'=>$published ? $published : '', 2214 'modified'=>$modified ? $modified : '' 2215 ]; 2216 } 2217 private function baiduseo_geo_category_form($id){ 2218 $term = $id ? get_term($id) : false; 2219 if(!$term || is_wp_error($term)){ 2220 return []; 2221 } 2222 $seo = get_option('baiduseo_cate_'.$id); 2223 $keywords = is_array($seo) && isset($seo['keywords']) ? $seo['keywords'] : ''; 2224 $description = is_array($seo) && isset($seo['description']) ? $seo['description'] : ''; 2225 if(!$description){ 2226 $description = term_description($id); 2227 $description = $description ? wp_strip_all_tags($description) : ''; 2228 } 2229 return [ 2230 'pageType'=>'category', 2231 'pageUrl'=>get_term_link($term), 2232 'seoTitle'=>$term->name, 2233 'seoKeywords'=>$keywords ? $keywords : '', 2234 'seoDesc'=>$description ? $description : '', 2235 'shareImage'=>'', 2236 'author'=>'', 2237 'published'=>'', 2238 'modified'=>'' 2239 ]; 2240 } 2241 private function baiduseo_geo_page_form($id){ 2242 $post = $id ? get_post($id) : false; 2243 if(!$post || $post->post_type !== 'page'){ 2244 return []; 2245 } 2246 $seo = get_post_meta($id, 'baiduseo_page', true); 2247 $keywords = is_array($seo) && isset($seo['keywords']) ? $seo['keywords'] : ''; 2248 $description = is_array($seo) && isset($seo['description']) ? $seo['description'] : ''; 2249 if(!$description && $post->post_excerpt){ 2250 $description = wp_strip_all_tags($post->post_excerpt); 2251 } 2252 return [ 2253 'pageType'=>'page', 2254 'pageUrl'=>get_permalink($id), 2255 'seoTitle'=>get_post_field('post_title', $id, 'raw'), 2256 'seoKeywords'=>$keywords ? $keywords : '', 2257 'seoDesc'=>$description ? $description : '', 2258 'shareImage'=>$this->baiduseo_get_geo_image($id), 2259 'author'=>get_the_author_meta('display_name', $post->post_author), 2260 'published'=>get_the_date('c', $id), 2261 'modified'=>get_the_modified_date('c', $id) 2262 ]; 2263 } 2264 private function baiduseo_geo_apply_form($config, $target_form){ 2265 $has_config = is_array($config); 2266 $config = is_array($config) ? $config : []; 2267 $saved_form = isset($config['form']) && is_array($config['form']) ? $config['form'] : []; 2268 $filtered_form = $this->baiduseo_geo_filter_saved_form($saved_form); 2269 $base_form = $has_config ? $filtered_form : $target_form; 2270 $config['form'] = array_merge($this->baiduseo_geo_default_form(), $base_form, $this->baiduseo_geo_webmaster_verify_form()); 2271 return $config; 2272 } 2273 public function baiduseo_get_geo(){ 2274 $this->check_permission('manage_options'); 2275 $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'home'; 2276 $id = isset($_POST['id']) ? (int)$_POST['id'] : 0; 2277 $reload = isset($_POST['reload']) ? (int)$_POST['reload'] : 0; 2278 if($type === 'page' && $id && $id === (int)get_option('page_on_front')){ 2279 $type = 'home'; 2280 } 2281 if($type === 'home'){ 2282 $data = get_option('baiduseo_geo_home'); 2283 $target_form = $this->baiduseo_geo_home_form(); 2284 }elseif($type === 'category'){ 2285 $data = $id ? get_option('baiduseo_geo_cate_'.$id) : []; 2286 $target_form = $this->baiduseo_geo_category_form($id); 2287 }elseif($type === 'page'){ 2288 $data = $id ? get_post_meta($id,'baiduseo_geo_page',true) : []; 2289 $target_form = $this->baiduseo_geo_page_form($id); 2290 }else{ 2291 echo wp_json_encode(['code'=>0,'msg'=>'类型错误']);exit; 2292 } 2293 if($reload){ 2294 $data = false; 2295 } 2296 $data = $this->baiduseo_geo_apply_form($data, $target_form); 2297 echo wp_json_encode(['code'=>1,'data'=>$data ? $data : []]);exit; 1689 2298 1690 2299 } … … 1701 2310 public function baiduseo_get_seo(){ 1702 2311 $this->check_permission('manage_options'); 2312 $llms_mode = isset($_POST['llms_mode']) ? sanitize_text_field(wp_unslash($_POST['llms_mode'])) : ''; 2313 if($llms_mode === 'reset'){ 2314 delete_option('seo_llms_builder'); 2315 } 1703 2316 1704 2317 $seo_init = get_option('seo_init'); … … 1711 2324 $seo_alt_auto['alt'] = get_option('seo_alt_auto'); 1712 2325 $rootbot['robots'] = get_option('seo_robots_sc'); 2326 $llms['llms'] = get_option('seo_llms_txt'); 2327 if(!is_array($llms['llms'])){ 2328 $llms['llms'] = [ 2329 'content'=>'', 2330 'time'=>'', 2331 'url'=>trim(get_option('home'),'/').'/llms.txt', 2332 'open'=>1, 2333 ]; 2334 } 2335 $llms['llms']['open'] = isset($llms['llms']['open']) ? (int)$llms['llms']['open'] : 1; 2336 $llms['llms']['builder'] = $this->baiduseo_llms_builder(); 1713 2337 $silian['silian'] = get_option('seo_baidu_silian'); 1714 2338 $blogname['biaoti'] = get_option('blogname'); 1715 2339 $blogdescription['fubiaoti'] = get_option('blogdescription'); 1716 $data = array_merge($seo_init,$seo_301_404_url,$sitemap,$seo_alt_auto,$rootbot,$ silian,$blogname,$blogdescription);2340 $data = array_merge($seo_init,$seo_301_404_url,$sitemap,$seo_alt_auto,$rootbot,$llms,$silian,$blogname,$blogdescription); 1717 2341 echo wp_json_encode(['code'=>1,'data'=>$data]);exit; 1718 2342 -
baiduseo/trunk/inc/admin/post.php
r3497150 r3625549 8 8 add_action('wp_ajax_'.$k, [$this,'baiduseo_ajax_post']); 9 9 } 10 add_action('wp_ajax_baiduseo_recommend_post_tags', [$this, 'baiduseo_recommend_post_tags']); 11 add_action('wp_ajax_baiduseo_ignore_post_tag', [$this, 'baiduseo_ignore_post_tag']); 10 12 } 11 13 public function baiduseo_get_option(){ … … 13 15 'baiduseo_zhizhu'=>1, 14 16 'baiduseo_seo'=>1, 17 'baiduseo_geo'=>1, 15 18 'baiduseo_zz'=>1, 16 19 'baiduseo_rank'=>1, … … 185 188 echo wp_json_encode(['code'=>0]);exit; 186 189 } 190 public function baiduseo_recommend_post_tags(){ 191 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'baiduseo')) { 192 echo wp_json_encode(['code'=>0]);exit; 193 } 194 $post_id = isset($_POST['post_id']) ? (int)$_POST['post_id'] : 0; 195 if (!$post_id || !current_user_can('edit_post', $post_id)) { 196 echo wp_json_encode(['code'=>0]);exit; 197 } 198 $baiduseo_tag = get_option('baiduseo_tag'); 199 if (!isset($baiduseo_tag['auto']) || (int)$baiduseo_tag['auto'] !== 0) { 200 echo wp_json_encode(['code'=>1,'data'=>[]]);exit; 201 } 202 $post = get_post($post_id); 203 if (!$post) { 204 echo wp_json_encode(['code'=>0]);exit; 205 } 206 $content_override = []; 207 if (isset($_POST['title'])) { 208 $content_override['title'] = sanitize_text_field(wp_unslash($_POST['title'])); 209 } 210 if (isset($_POST['content'])) { 211 $content_override['content'] = wp_kses_post(wp_unslash($_POST['content'])); 212 } 213 echo wp_json_encode([ 214 'code'=>1, 215 'data'=>baiduseo_common::baiduseo_get_post_tag_recommendations($post_id, $this->baiduseo_get_ignored_post_tags($post_id), $content_override) 216 ]);exit; 217 } 218 public function baiduseo_ignore_post_tag(){ 219 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'baiduseo')) { 220 echo wp_json_encode(['code'=>0]);exit; 221 } 222 $post_id = isset($_POST['post_id']) ? (int)$_POST['post_id'] : 0; 223 $term_id = isset($_POST['term_id']) ? (int)$_POST['term_id'] : 0; 224 if (!$post_id || !$term_id || !current_user_can('edit_post', $post_id)) { 225 echo wp_json_encode(['code'=>0]);exit; 226 } 227 $ignored = $this->baiduseo_get_ignored_post_tags($post_id); 228 if (!in_array($term_id, $ignored, true)) { 229 $ignored[] = $term_id; 230 } 231 update_post_meta($post_id, '_baiduseo_ignored_recommend_tags', $ignored); 232 echo wp_json_encode([ 233 'code'=>1, 234 'data'=>baiduseo_common::baiduseo_get_post_tag_recommendations($post_id, $ignored) 235 ]);exit; 236 } 237 private function baiduseo_get_ignored_post_tags($post_id){ 238 $ignored = get_post_meta($post_id, '_baiduseo_ignored_recommend_tags', true); 239 return is_array($ignored) ? array_map('intval', $ignored) : []; 240 } 187 241 public function baiduseo_ajax_post(){ 188 242 if (!current_user_can('manage_options')) { … … 200 254 echo wp_json_encode(['code'=>0]);exit; 201 255 256 } 257 258 private function baiduseo_geo_sanitize_config($config){ 259 $data = json_decode($config, true); 260 if(!is_array($data)){ 261 return false; 262 } 263 $out = []; 264 if(isset($data['form']) && is_array($data['form'])){ 265 $out['form'] = []; 266 foreach($data['form'] as $key=>$value){ 267 $key = preg_replace('/[^A-Za-z0-9_]/', '', $key); 268 $out['form'][$key] = is_string($value) ? sanitize_textarea_field($value) : $value; 269 } 270 } 271 if(isset($data['switchState']) && is_array($data['switchState'])){ 272 $out['switchState'] = []; 273 foreach($data['switchState'] as $key=>$value){ 274 $key = preg_replace('/[^A-Za-z0-9_]/', '', $key); 275 $out['switchState'][$key] = $value ? 1 : 0; 276 } 277 } 278 if(isset($data['schemaSource']) && is_array($data['schemaSource'])){ 279 $out['schemaSource'] = []; 280 foreach($data['schemaSource'] as $key=>$value){ 281 $key = preg_replace('/[^A-Za-z0-9_]/', '', $key); 282 $value = sanitize_text_field($value); 283 $out['schemaSource'][$key] = in_array($value, ['auto','manual','none'], true) ? $value : 'auto'; 284 } 285 } 286 if(isset($data['activeSchemaMode'])){ 287 $active_schema_mode = sanitize_text_field($data['activeSchemaMode']); 288 $out['activeSchemaMode'] = in_array($active_schema_mode, ['builder','custom'], true) ? $active_schema_mode : 'builder'; 289 } 290 return $out; 291 } 292 293 private function baiduseo_geo_source_form_keys(){ 294 return ['pageType','pageUrl','seoTitle','seoKeywords','seoDesc','shareImage','shareImageId','author','published','modified']; 295 } 296 297 private function baiduseo_geo_schema_source_form_map(){ 298 return [ 299 'title'=>'seoTitle', 300 'desc'=>'seoDesc', 301 'url'=>'pageUrl', 302 'image'=>'shareImage', 303 'author'=>'author', 304 'published'=>'published', 305 'modified'=>'modified' 306 ]; 307 } 308 309 private function baiduseo_geo_strip_source_form($config){ 310 return $config; 311 } 312 313 private function baiduseo_geo_form_text($config, $key){ 314 return isset($config['form'][$key]) ? sanitize_text_field($config['form'][$key]) : ''; 315 } 316 317 private function baiduseo_geo_form_textarea($config, $key){ 318 return isset($config['form'][$key]) ? sanitize_textarea_field($config['form'][$key]) : ''; 319 } 320 321 private function baiduseo_geo_sync_source_form($type, $id, $config){ 322 if(!isset($config['form']) || !is_array($config['form'])) return; 323 $title = $this->baiduseo_geo_form_text($config, 'seoTitle'); 324 $keywords = $this->baiduseo_geo_form_text($config, 'seoKeywords'); 325 $description = $this->baiduseo_geo_form_textarea($config, 'seoDesc'); 326 if($type === 'home'){ 327 update_option('seo_init',['keywords'=>$keywords,'description'=>$description]); 328 $front_page_id = (int)get_option('page_on_front'); 329 if($front_page_id && $title !== ''){ 330 wp_update_post(['ID'=>$front_page_id,'post_title'=>$title]); 331 } 332 }elseif($type === 'category' && $id){ 333 update_option('baiduseo_cate_'.$id,['keywords'=>$keywords,'description'=>$description]); 334 if($title !== ''){ 335 wp_update_term($id, 'category', ['name'=>$title]); 336 } 337 }elseif($type === 'page' && $id){ 338 update_post_meta($id,'baiduseo_page',['keywords'=>$keywords,'description'=>$description]); 339 if($title !== ''){ 340 wp_update_post(['ID'=>$id,'post_title'=>$title]); 341 } 342 } 343 } 344 345 public function baiduseo_geo($log,$log1,$log2){ 346 if(isset($_POST['nonce']) && isset($_POST['action']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])),'baiduseo')){ 347 $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'home'; 348 $id = isset($_POST['id']) ? (int)$_POST['id'] : 0; 349 if($type === 'page' && $id && $id === (int)get_option('page_on_front')){ 350 $type = 'home'; 351 } 352 $config_raw = isset($_POST['config']) ? sanitize_textarea_field(wp_unslash($_POST['config'])) : ''; 353 $config = $config_raw !== '' ? $this->baiduseo_geo_sanitize_config($config_raw) : false; 354 if(!$config){ 355 echo wp_json_encode(['msg'=>'配置格式错误','code'=>0]);exit; 356 } 357 $this->baiduseo_geo_sync_source_form($type, $id, $config); 358 $config = $this->baiduseo_geo_strip_source_form($config); 359 if($type === 'home'){ 360 update_option('baiduseo_geo_home',$config); 361 }elseif($type === 'category'){ 362 if(!$id){ 363 echo wp_json_encode(['msg'=>'请选择分类','code'=>0]);exit; 364 } 365 update_option('baiduseo_geo_cate_'.$id,$config); 366 }elseif($type === 'page'){ 367 if(!$id){ 368 echo wp_json_encode(['msg'=>'请选择页面','code'=>0]);exit; 369 } 370 update_post_meta($id,'baiduseo_geo_page',$config); 371 }else{ 372 echo wp_json_encode(['msg'=>'类型错误','code'=>0]);exit; 373 } 374 echo wp_json_encode(['msg'=>'保存成功','code'=>1]);exit; 375 } 376 echo wp_json_encode(['msg'=>'保存失败','code'=>0]);exit; 202 377 } 203 378 … … 1946 2121 $need = $tag_num - $existing; 1947 2122 $added = 0; 1948 $insert_ sql= [];2123 $insert_rows = []; 1949 2124 1950 2125 foreach ($tags as $tag) { … … 1964 2139 if ($has) continue; 1965 2140 1966 $insert_sql[] = $wpdb->prepare("(%d,%d)", $post_id, $tag['term_taxonomy_id']); 2141 $insert_rows[] = [ 2142 'object_id' => (int)$post_id, 2143 'term_taxonomy_id' => (int)$tag['term_taxonomy_id'], 2144 ]; 1967 2145 $added++; 1968 2146 } 1969 2147 1970 2148 // 批量插入(仅1次数据库交互) 1971 if (!empty($insert_sql)) { 1972 $wpdb->query( 1973 "INSERT INTO {$wpdb->prefix}term_relationships (object_id, term_taxonomy_id) 1974 VALUES " . implode(',', $insert_sql) 1975 ); 2149 if (!empty($insert_rows)) { 2150 foreach ($insert_rows as $insert_row) { 2151 $wpdb->insert( 2152 $wpdb->prefix . 'term_relationships', 2153 $insert_row, 2154 ['%d', '%d'] 2155 ); 2156 } 1976 2157 } 1977 2158 } … … 2392 2573 // 处理多文章类型参数(逗号分割) 2393 2574 //判断是标签还是内敛 2394 if(!isset($_POST['name']) && isset($_POST['content']) && is_string($_POST['content']) && strpos($_POST['content'],',') === false){ 2575 $tag_content = isset($_POST['content']) ? sanitize_textarea_field(wp_unslash($_POST['content'])) : ''; 2576 if(!isset($_POST['name']) && $tag_content !== '' && strpos($tag_content,',') === false){ 2395 2577 echo wp_json_encode(['msg' => '格式不正确,请更正后尝试。', 'code' => 0]); 2396 2578 exit; … … 2429 2611 // 原有验证逻辑 2430 2612 2431 if ( isset($_POST['content']) && sanitize_textarea_field(wp_unslash($_POST['content']))) {2613 if ($tag_content !== '') { 2432 2614 $baiduseo_wzt_log = baiduseo_kp::baiduseo_wzt_log(); 2433 2615 if (!$baiduseo_wzt_log) { … … 2440 2622 exit; 2441 2623 } 2442 $content = explode("\n", sanitize_textarea_field(wp_unslash($_POST['content'])));2624 $content = explode("\n", $tag_content); 2443 2625 $baiduseo_tag_manage = get_option('baiduseo_tag'); 2444 2626 if (!empty($content)) { … … 2487 2669 $taxonomy // 动态标签分类法 2488 2670 ); 2489 2671 2490 2672 // 处理标签创建失败(如重复创建的错误) 2491 2673 if (is_wp_error($term)) { 2492 2674 continue; 2493 2675 } 2494 2676 2495 2677 $term_id = $term['term_id']; 2496 2678 $term_taxonomy_id = $term['term_taxonomy_id']; 2497 2679 2498 2680 // 处理标签别名(slug) 2499 2681 if (!isset($baiduseo_tag_manage['taglink']) || !$baiduseo_tag_manage['taglink']) { … … 2506 2688 ); 2507 2689 } 2508 2509 // 自动关联标签到对应文章类型的文章 2510 if ($baiduseo_tag_manage && isset($baiduseo_tag_manage['auto']) && $baiduseo_tag_manage['auto']) { 2511 // 查询当前文章类型的已发布文章 2512 $articles = $wpdb->get_results( 2513 $wpdb->prepare( 2514 'select * from ' . $wpdb->prefix . 'posts 2515 where post_status = "publish" and post_type = %s 2516 order by ID desc limit 1000', 2517 $post_type 2518 ), 2519 ARRAY_A 2520 ); 2521 2522 if (!isset($baiduseo_tag_manage['num']) || !$baiduseo_tag_manage['num'] || $baiduseo_tag_manage['num'] == 11) { 2523 foreach ($articles as $article) { 2524 $this->bind_tag_to_article($article, $term_taxonomy_id, $taxonomy, $tag[0], $baiduseo_tag_manage, $wpdb); 2690 } else { 2691 $term_id = $terms[0]['term_id']; 2692 $term_taxonomy = $wpdb->get_results($wpdb->prepare( 2693 'select term_taxonomy_id from ' . $wpdb->prefix . 'term_taxonomy where taxonomy = %s and term_id = %d', 2694 $taxonomy, 2695 $term_id 2696 ), ARRAY_A); 2697 if (empty($term_taxonomy)) { 2698 continue; 2699 } 2700 $term_taxonomy_id = $term_taxonomy[0]['term_taxonomy_id']; 2701 } 2702 2703 // 自动模式下,无论标签是新建还是已存在,都执行关联逻辑 2704 if ($baiduseo_tag_manage && isset($baiduseo_tag_manage['auto']) && $baiduseo_tag_manage['auto']) { 2705 // 查询当前文章类型的已发布文章 2706 $articles = $wpdb->get_results( 2707 $wpdb->prepare( 2708 'select * from ' . $wpdb->prefix . 'posts 2709 where post_status = "publish" and post_type = %s 2710 order by ID desc limit 1000', 2711 $post_type 2712 ), 2713 ARRAY_A 2714 ); 2715 2716 if (!isset($baiduseo_tag_manage['num']) || !$baiduseo_tag_manage['num'] || $baiduseo_tag_manage['num'] == 11) { 2717 foreach ($articles as $article) { 2718 $this->bind_tag_to_article($article, $term_taxonomy_id, $taxonomy, $tag[0], $baiduseo_tag_manage, $wpdb); 2719 } 2720 } else { 2721 foreach ($articles as $article) { 2722 // 检查文章在当前分类法下的已有标签数量 2723 $tag_count = $wpdb->query($wpdb->prepare( 2724 'select * from ' . $wpdb->prefix . 'term_relationships as a 2725 left join ' . $wpdb->prefix . 'term_taxonomy as b on a.term_taxonomy_id = b.term_taxonomy_id 2726 where b.taxonomy = %s and a.object_id = %d', 2727 $taxonomy, 2728 $article['ID'] 2729 )); 2730 if ($tag_count >= $baiduseo_tag_manage['num']) { 2731 break; 2525 2732 } 2526 } else { 2527 foreach ($articles as $article) { 2528 // 检查文章在当前分类法下的已有标签数量 2529 $tag_count = $wpdb->query($wpdb->prepare( 2530 'select * from ' . $wpdb->prefix . 'term_relationships as a 2531 left join ' . $wpdb->prefix . 'term_taxonomy as b on a.term_taxonomy_id = b.term_taxonomy_id 2532 where b.taxonomy = %s and a.object_id = %d', 2533 $taxonomy, 2534 $article['ID'] 2535 )); 2536 if ($tag_count >= $baiduseo_tag_manage['num']) { 2537 break; 2538 } 2539 $this->bind_tag_to_article($article, $term_taxonomy_id, $taxonomy, $tag[0], $baiduseo_tag_manage, $wpdb); 2540 } 2733 $this->bind_tag_to_article($article, $term_taxonomy_id, $taxonomy, $tag[0], $baiduseo_tag_manage, $wpdb); 2541 2734 } 2542 2735 } … … 2568 2761 // 匹配文章内容中的关键词,成功则关联标签 2569 2762 if (preg_match($pattern, $article['post_content'], $matches)) { 2763 $exists = $wpdb->get_var($wpdb->prepare( 2764 'select object_id from ' . $wpdb->prefix . 'term_relationships where object_id = %d and term_taxonomy_id = %d', 2765 $article['ID'], 2766 $term_taxonomy_id 2767 )); 2768 if ($exists) { 2769 return; 2770 } 2771 2570 2772 // 关联标签到文章 2571 2773 $wpdb->insert( … … 3019 3221 baiduseo_seo::robots(sanitize_textarea_field(wp_unslash($_POST['robots']))); 3020 3222 } 3223 $llms_open = isset($_POST['llms_open']) ? (int)$_POST['llms_open'] : 1; 3224 if(isset($_POST['llms_open'])){ 3225 baiduseo_seo::llms_open($llms_open); 3226 } 3227 if($llms_open && isset($_POST['llms_txt'])){ 3228 baiduseo_seo::llms_txt(sanitize_textarea_field(wp_unslash($_POST['llms_txt']))); 3229 } 3230 if(isset($_POST['llms_builder'])){ 3231 baiduseo_seo::llms_builder(sanitize_textarea_field(wp_unslash($_POST['llms_builder']))); 3232 } 3021 3233 3022 3234 $sitemap = get_option('seo_baidu_sitemap'); -
baiduseo/trunk/inc/admin/seo.php
r3497150 r3625549 475 475 }else{ 476 476 add_option('seo_robots_sc',$robot); 477 } 478 } 479 public static function llms_txt($content){ 480 $url =trim(get_option('home'),'/').'/llms.txt'; 481 $currnetTime= current_time( 'Y/m/d H:i:s'); 482 $llms = [ 483 'content'=>$content, 484 'time'=>$currnetTime, 485 'url'=>$url, 486 'open'=>1, 487 ]; 488 WP_Filesystem(); 489 global $wp_filesystem; 490 491 $wp_filesystem->put_contents( ABSPATH .'/llms.txt',"\xEF\xBB\xBF".$content); 492 $llms_txt = get_option('seo_llms_txt'); 493 if($llms_txt!==false){ 494 update_option('seo_llms_txt',$llms); 495 }else{ 496 add_option('seo_llms_txt',$llms); 497 } 498 } 499 public static function llms_open($open){ 500 $url =trim(get_option('home'),'/').'/llms.txt'; 501 $llms_txt = get_option('seo_llms_txt'); 502 if(!is_array($llms_txt)){ 503 $llms_txt = [ 504 'content'=>'', 505 'time'=>'', 506 'url'=>$url, 507 ]; 508 } 509 $llms_txt['open'] = $open ? 1 : 0; 510 $llms_txt['url'] = $url; 511 if(!$open){ 512 $llms_txt['content'] = ''; 513 $llms_txt['time'] = ''; 514 WP_Filesystem(); 515 global $wp_filesystem; 516 if($wp_filesystem->exists(ABSPATH .'/llms.txt')){ 517 $wp_filesystem->delete(ABSPATH .'/llms.txt'); 518 } 519 } 520 if(get_option('seo_llms_txt')!==false){ 521 update_option('seo_llms_txt',$llms_txt); 522 }else{ 523 add_option('seo_llms_txt',$llms_txt); 524 } 525 } 526 private static function llms_clean_entry($item,$keep_identity = false){ 527 if(!is_array($item)){ 528 return []; 529 } 530 $entry = [ 531 'id'=>isset($item['id']) ? sanitize_text_field($item['id']) : '', 532 'desc'=>isset($item['desc']) ? sanitize_textarea_field($item['desc']) : '', 533 'checked'=>!empty($item['checked']), 534 ]; 535 if($keep_identity){ 536 $entry['title'] = isset($item['title']) ? sanitize_text_field($item['title']) : ''; 537 $entry['url'] = isset($item['url']) ? esc_url_raw($item['url']) : ''; 538 } 539 return $entry; 540 } 541 private static function llms_clean_entries($items,$keep_identity = false){ 542 $data = []; 543 if(!is_array($items)){ 544 return $data; 545 } 546 foreach($items as $item){ 547 $entry = self::llms_clean_entry($item,$keep_identity); 548 if($entry){ 549 $data[] = $entry; 550 } 551 } 552 return $data; 553 } 554 private static function llms_clean_custom_modules($items){ 555 $data = []; 556 if(!is_array($items)){ 557 return $data; 558 } 559 foreach($items as $item){ 560 if(!is_array($item)){ 561 continue; 562 } 563 $data[] = [ 564 'id'=>isset($item['id']) ? sanitize_text_field($item['id']) : '', 565 'title'=>isset($item['title']) ? sanitize_text_field($item['title']) : '', 566 'content'=>isset($item['content']) ? sanitize_textarea_field($item['content']) : '', 567 'enabled'=>!empty($item['enabled']), 568 ]; 569 } 570 return $data; 571 } 572 private static function llms_clean_entry_groups($items){ 573 $data = []; 574 if(!is_array($items)){ 575 return $data; 576 } 577 foreach($items as $item){ 578 if(!is_array($item)){ 579 continue; 580 } 581 $data[] = [ 582 'id'=>isset($item['id']) ? sanitize_text_field($item['id']) : '', 583 'title'=>isset($item['title']) && sanitize_text_field($item['title']) ? sanitize_text_field($item['title']) : '自定义入口', 584 'enabled'=>!empty($item['enabled']), 585 'links'=>self::llms_clean_entries(isset($item['links']) ? $item['links'] : [],true), 586 ]; 587 } 588 return $data; 589 } 590 public static function llms_builder($builder){ 591 if(is_string($builder)){ 592 $builder = json_decode(sanitize_textarea_field($builder),true); 593 } 594 if(!is_array($builder)){ 595 $builder = []; 596 } 597 $form = isset($builder['form']) && is_array($builder['form']) ? $builder['form'] : []; 598 $data = [ 599 'form'=>[ 600 'siteName'=>isset($form['siteName']) ? sanitize_text_field($form['siteName']) : '', 601 'language'=>isset($form['language']) ? sanitize_text_field($form['language']) : 'zh-CN', 602 'sitemapUrl'=>isset($form['sitemapUrl']) ? esc_url_raw($form['sitemapUrl']) : '', 603 'siteIntro'=>isset($form['siteIntro']) ? sanitize_textarea_field($form['siteIntro']) : '', 604 'businessScope'=>isset($form['businessScope']) ? sanitize_textarea_field($form['businessScope']) : '', 605 'targetUsers'=>isset($form['targetUsers']) ? sanitize_textarea_field($form['targetUsers']) : '', 606 'serviceArea'=>isset($form['serviceArea']) ? sanitize_textarea_field($form['serviceArea']) : '', 607 ], 608 'pages'=>self::llms_clean_entries(isset($builder['pages']) ? $builder['pages'] : []), 609 'posts'=>self::llms_clean_entries(isset($builder['posts']) ? $builder['posts'] : []), 610 'categories'=>self::llms_clean_entries(isset($builder['categories']) ? $builder['categories'] : []), 611 'manualLinks'=>self::llms_clean_entries(isset($builder['manualLinks']) ? $builder['manualLinks'] : [],true), 612 'entryGroups'=>self::llms_clean_entry_groups(isset($builder['entryGroups']) ? $builder['entryGroups'] : []), 613 'customModules'=>self::llms_clean_custom_modules(isset($builder['customModules']) ? $builder['customModules'] : []), 614 ]; 615 $llms_builder = get_option('seo_llms_builder'); 616 if($llms_builder!==false){ 617 update_option('seo_llms_builder',$data); 618 }else{ 619 add_option('seo_llms_builder',$data); 477 620 } 478 621 } -
baiduseo/trunk/inc/admin/zhizhu.php
r3497150 r3625549 187 187 ); 188 188 189 $data_array['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? ($_SERVER['REMOTE_ADDR'] ?? ''); 189 $forwarded_for = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR'])) : ''; 190 $remote_addr = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : ''; 191 $data_array['ip'] = $forwarded_for !== '' ? $forwarded_for : $remote_addr; 190 192 $data_array['time'] = current_time('Y/m/d H:i:s'); 191 193 $data_array['type'] = http_response_code(); … … 219 221 ); 220 222 221 $data_array['ip'] = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? ($_SERVER['REMOTE_ADDR'] ?$_SERVER['REMOTE_ADDR']: ''); 223 $forwarded_for = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR'])) : ''; 224 $remote_addr = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : ''; 225 $data_array['ip'] = $forwarded_for !== '' ? $forwarded_for : $remote_addr; 222 226 $data_array['time'] = current_time('Y/m/d H:i:s'); 223 227 $data_array['type'] = http_response_code(); … … 538 542 } 539 543 $start = ($page-1)*$limit; 544 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are fixed branches; user values are prepared via placeholders. 540 545 $count = $wpdb->query($wpdb->prepare($sql,$search,$sta,$end,$type,$type2)); 541 546 if($orders==1){ … … 546 551 $sql .= 'order by time desc limit %d,%d '; 547 552 } 553 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL clauses above are fixed branches; user values are prepared via placeholders. 548 554 $zhizhu = $wpdb->get_results($wpdb->prepare($sql,$search,$sta,$end,$type,$type2,$start,$limit),ARRAY_A); 549 555 $baiduseo_zhizhu = get_option('baiduseo_zhizhu'); -
baiduseo/trunk/inc/common/index.php
r3501273 r3625549 78 78 if (isset($_POST['nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'baiduseo_front')) { 79 79 80 $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(strtolower(wp_unslash($_SERVER['HTTP_USER_AGENT']))) : ''; 80 $userAgent = ''; 81 if (isset($_SERVER['HTTP_USER_AGENT'])) { 82 $userAgent = sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])); 83 $userAgent = strtolower($userAgent); 84 } 81 85 82 86 if (empty($userAgent)) { … … 350 354 var now = Date.now(); 351 355 352 var saved = localStorage.getItem(STORAGE_KEY);353 if (saved) {354 try {355 var parsed = JSON.parse(saved);356 if (parsed && parsed.type && parsed.timestamp) {357 var ageDays = (now - parsed.timestamp) / (86400000);358 if (ageDays < EXPIRY_DAYS) {359 return parsed;360 } else {361 localStorage.removeItem(STORAGE_KEY);362 }363 }364 } catch (e) {365 localStorage.removeItem(STORAGE_KEY);366 }367 }368 369 356 var adParams = ['utm_medium', 'utm_source', 'utm_campaign', 'gclid', 'fbclid', 'ttclid', 'msclkid']; 370 357 var searchEngines = ['google.', 'bing.', 'yahoo.', 'baidu.', 'sogou.', 'so.com', 'duckduckgo.', 'yandex.', 'sm.cn', 'ecosia.']; 358 var aiSources = ['chatgpt.com', 'chat.openai.com', 'openai.com', 'perplexity.ai', 'pplx.ai', 'claude.ai', 'poe.com', 'you.com', 'gemini.google.com', 'bard.google.com', 'copilot.microsoft.com', 'bing.com/chat', 'metaso.cn', 'kimi.moonshot.cn', 'kimi.com', 'doubao.com', 'link.wttur.cn', 'yuanbao.tencent.com', 'ima.qq.com', 'tongyi.aliyun.com', 'qianwen.aliyun.com', 'yiyan.baidu.com', 'chat.baidu.com', 'deepseek.com', 'deepseek.ai', 'chatglm.cn', 'zhipuai.cn', 'coze.cn', 'grok.com', 'x.ai']; 371 359 var traffic = { type: 'direct', referrer: null, detail: '直接访问', timestamp: now }; 360 var baiduseoSource = (params.get('baiduseo_source') || '').toLowerCase(); 361 362 if (baiduseoSource === 'ai') { 363 traffic = { type: 'ai', referrer: ref || null, detail: 'AI来源', timestamp: now }; 364 } 372 365 373 366 /* 检测广告 */ 374 for (var i = 0; i < adParams.length; i++) { 375 if (params.has(adParams[i])) { 376 traffic = { type: 'paid', referrer: ref || null, detail: '付费访问', timestamp: now }; 377 break; 367 if (traffic.type === 'direct') { 368 for (var i = 0; i < adParams.length; i++) { 369 if (params.has(adParams[i])) { 370 traffic = { type: 'paid', referrer: ref || null, detail: '付费访问', timestamp: now }; 371 break; 372 } 373 } 374 } 375 376 /* 检测 AI 来源 */ 377 if (traffic.type === 'direct') { 378 if (ref) { 379 var aiRefLower = ref.toLowerCase(); 380 for (var aiIndex = 0; aiIndex < aiSources.length; aiIndex++) { 381 if (aiRefLower.indexOf(aiSources[aiIndex]) !== -1) { 382 traffic = { type: 'ai', referrer: ref, detail: 'AI来源', timestamp: now }; 383 break; 384 } 385 } 378 386 } 379 387 } … … 393 401 if (traffic.type === 'direct' && ref && ref.indexOf(siteDomain) === -1) { 394 402 traffic = { type: 'referral', referrer: ref, detail: '外部链接', timestamp: now }; 403 } 404 405 if (traffic.type === 'direct') { 406 var saved = localStorage.getItem(STORAGE_KEY); 407 if (saved) { 408 try { 409 var parsed = JSON.parse(saved); 410 if (parsed && parsed.type && parsed.timestamp) { 411 var ageDays = (now - parsed.timestamp) / (86400000); 412 if (ageDays < EXPIRY_DAYS) { 413 return parsed; 414 } else { 415 localStorage.removeItem(STORAGE_KEY); 416 } 417 } 418 } catch (e) { 419 localStorage.removeItem(STORAGE_KEY); 420 } 421 } 395 422 } 396 423 … … 409 436 $safe_session = ''; 410 437 if (isset($_SESSION['baiduseo_liulan'])) { 411 $safe_session = $_SESSION['baiduseo_liulan'];438 $safe_session = sanitize_text_field(wp_unslash($_SESSION['baiduseo_liulan'])); 412 439 } 413 440 echo json_encode($safe_session); … … 939 966 } 940 967 } 968 $this->baiduseo_geo_output(); 969 } 970 private function baiduseo_geo_current_config() 971 { 972 if (is_front_page() || is_home()) { 973 return get_option('baiduseo_geo_home'); 974 } 975 if (is_category()) { 976 $term_id = get_queried_object_id(); 977 return $term_id ? get_option('baiduseo_geo_cate_' . $term_id) : []; 978 } 979 if (is_page()) { 980 global $post; 981 return isset($post->ID) ? get_post_meta($post->ID, 'baiduseo_geo_page', true) : []; 982 } 983 return []; 984 } 985 private function baiduseo_geo_source_form() 986 { 987 if (is_front_page() || is_home()) { 988 $seo = get_option('seo_init'); 989 $front_page_id = (int)get_option('page_on_front'); 990 $title = get_bloginfo('name'); 991 $image = ''; 992 $author = ''; 993 $published = ''; 994 $modified = ''; 995 if ($front_page_id) { 996 $front_page = get_post($front_page_id); 997 if ($front_page && $front_page->post_type === 'page') { 998 $title = get_post_field('post_title', $front_page_id, 'raw'); 999 $image = get_the_post_thumbnail_url($front_page_id, 'full'); 1000 $author = get_the_author_meta('display_name', $front_page->post_author); 1001 $published = get_the_date('c', $front_page_id); 1002 $modified = get_the_modified_date('c', $front_page_id); 1003 } 1004 } 1005 if (!$image) { 1006 $custom_logo_id = get_theme_mod('custom_logo'); 1007 if ($custom_logo_id) $image = wp_get_attachment_image_url($custom_logo_id, 'full'); 1008 } 1009 return [ 1010 'pageType' => 'website', 1011 'pageUrl' => home_url('/'), 1012 'seoTitle' => $title ? $title : '', 1013 'seoKeywords' => is_array($seo) && isset($seo['keywords']) ? $seo['keywords'] : '', 1014 'seoDesc' => is_array($seo) && isset($seo['description']) ? $seo['description'] : '', 1015 'shareImage' => $image ? $image : '', 1016 'author' => $author ? $author : '', 1017 'published' => $published ? $published : '', 1018 'modified' => $modified ? $modified : '' 1019 ]; 1020 } 1021 if (is_category()) { 1022 $term_id = get_queried_object_id(); 1023 $term = $term_id ? get_term($term_id) : false; 1024 if (!$term || is_wp_error($term)) return []; 1025 $seo = get_option('baiduseo_cate_' . $term_id); 1026 $description = is_array($seo) && isset($seo['description']) ? $seo['description'] : ''; 1027 if (!$description) { 1028 $description = term_description($term_id); 1029 $description = $description ? wp_strip_all_tags($description) : ''; 1030 } 1031 return [ 1032 'pageType' => 'category', 1033 'pageUrl' => get_term_link($term), 1034 'seoTitle' => $term->name, 1035 'seoKeywords' => is_array($seo) && isset($seo['keywords']) ? $seo['keywords'] : '', 1036 'seoDesc' => $description ? $description : '', 1037 'shareImage' => '', 1038 'author' => '', 1039 'published' => '', 1040 'modified' => '' 1041 ]; 1042 } 1043 if (is_page()) { 1044 global $post; 1045 if (!isset($post->ID)) return []; 1046 $seo = get_post_meta($post->ID, 'baiduseo_page', true); 1047 $description = is_array($seo) && isset($seo['description']) ? $seo['description'] : ''; 1048 if (!$description && $post->post_excerpt) $description = wp_strip_all_tags($post->post_excerpt); 1049 return [ 1050 'pageType' => 'page', 1051 'pageUrl' => get_permalink($post->ID), 1052 'seoTitle' => get_post_field('post_title', $post->ID, 'raw'), 1053 'seoKeywords' => is_array($seo) && isset($seo['keywords']) ? $seo['keywords'] : '', 1054 'seoDesc' => $description ? $description : '', 1055 'shareImage' => get_the_post_thumbnail_url($post->ID, 'full'), 1056 'author' => get_the_author_meta('display_name', $post->post_author), 1057 'published' => get_the_date('c', $post->ID), 1058 'modified' => get_the_modified_date('c', $post->ID) 1059 ]; 1060 } 1061 return []; 1062 } 1063 private function baiduseo_geo_form_value($form, $key) 1064 { 1065 return isset($form[$key]) && is_scalar($form[$key]) ? trim((string)$form[$key]) : ''; 1066 } 1067 private function baiduseo_geo_switch_open($switch, $key) 1068 { 1069 return isset($switch[$key]) && $switch[$key]; 1070 } 1071 private function baiduseo_geo_meta($name, $value, $type = 'name') 1072 { 1073 $value = trim((string)$value); 1074 if ($value === '') return ''; 1075 $attr = $type === 'property' ? 'property' : 'name'; 1076 return '<meta ' . $attr . '="' . esc_attr($name) . '" content="' . esc_attr($value) . '">' . "\n"; 1077 } 1078 private function baiduseo_geo_verify_content($value) 1079 { 1080 $value = trim((string)$value); 1081 if ($value === '') return ''; 1082 $value = sanitize_text_field(html_entity_decode($value, ENT_QUOTES, get_bloginfo('charset'))); 1083 if ($value === '' || strlen($value) > 256) return ''; 1084 if (!preg_match('/^[A-Za-z0-9._:-]+$/', $value)) return ''; 1085 return $value; 1086 } 1087 private function baiduseo_geo_webmaster_verify_meta() 1088 { 1089 $baiduseo_zz = []; 1090 if (class_exists('baiduseo_set') && class_exists('baiduseo_kp')) { 1091 $baiduseo_zz = baiduseo_set::baiduseo_get_option(baiduseo_kp::baiduseo_wzt_log(), 'baiduseo_zz'); 1092 } 1093 if (empty($baiduseo_zz)) $baiduseo_zz = get_option('baiduseo_zz'); 1094 if (!is_array($baiduseo_zz)) return ''; 1095 $html = ''; 1096 $zz_link = isset($baiduseo_zz['zz_link']) ? trim((string)$baiduseo_zz['zz_link']) : ''; 1097 if ($zz_link !== '') { 1098 $query = wp_parse_url(str_replace('&', '&', $zz_link), PHP_URL_QUERY); 1099 if ($query) { 1100 parse_str($query, $params); 1101 $baidu_token = isset($params['token']) ? $this->baiduseo_geo_verify_content($params['token']) : ''; 1102 $html .= $this->baiduseo_geo_meta('baidu-site-verification', $baidu_token); 1103 } 1104 } 1105 $bing_key = isset($baiduseo_zz['bing_key']) ? $this->baiduseo_geo_verify_content($baiduseo_zz['bing_key']) : ''; 1106 $html .= $this->baiduseo_geo_meta('msvalidate.01', $bing_key); 1107 return $html; 1108 } 1109 private function baiduseo_geo_itemprop($name, $value) 1110 { 1111 $value = trim((string)$value); 1112 if ($value === '') return ''; 1113 return '<meta itemprop="' . esc_attr($name) . '" content="' . esc_attr($value) . '">' . "\n"; 1114 } 1115 private function baiduseo_geo_same_as($form) 1116 { 1117 $same_as = []; 1118 foreach (['wechat', 'weibo', 'zhihu', 'bili', 'xurl', 'linkedin', 'facebook', 'youtube'] as $key) { 1119 $value = $this->baiduseo_geo_form_value($form, $key); 1120 if ($value !== '') $same_as[] = $value; 1121 } 1122 return $same_as; 1123 } 1124 private function baiduseo_geo_current_value($key, $form) 1125 { 1126 $field_map = [ 1127 'title' => 'seoTitle', 1128 'desc' => 'seoDesc', 1129 'url' => 'pageUrl', 1130 'image' => 'shareImage', 1131 'author' => 'author', 1132 'published' => 'published', 1133 'modified' => 'modified' 1134 ]; 1135 if (!isset($field_map[$key])) return ''; 1136 return $this->baiduseo_geo_form_value($form, $field_map[$key]); 1137 } 1138 private function baiduseo_geo_output_value($key, $form, $schema_source, $source_form = []) 1139 { 1140 $source = isset($schema_source[$key]) ? $schema_source[$key] : 'auto'; 1141 if ($source === 'none') return ''; 1142 if ($source === 'auto') return $this->baiduseo_geo_current_value($key, $source_form); 1143 return $this->baiduseo_geo_current_value($key, $form); 1144 } 1145 private function baiduseo_geo_schema_type($form) 1146 { 1147 $schema_type = $this->baiduseo_geo_form_value($form, 'schemaType'); 1148 $page_type = $this->baiduseo_geo_form_value($form, 'pageType'); 1149 if ($schema_type === 'CollectionPage' || $page_type === 'category') return 'CollectionPage'; 1150 if ($schema_type === 'FAQPage' && $this->baiduseo_geo_faq_items($this->baiduseo_geo_form_value($form, 'faqText'))) return 'FAQPage'; 1151 if ($schema_type === 'Article' || $page_type === 'article') return ['Article', 'BlogPosting']; 1152 return 'WebPage'; 1153 } 1154 private function baiduseo_geo_strip_empty($value) 1155 { 1156 if (is_array($value)) { 1157 $out = []; 1158 foreach ($value as $key => $item) { 1159 $item = $this->baiduseo_geo_strip_empty($item); 1160 if ($item !== '' && $item !== null && $item !== []) $out[$key] = $item; 1161 } 1162 return $out; 1163 } 1164 return $value; 1165 } 1166 private function baiduseo_geo_faq_items($faq_text) 1167 { 1168 $faq_text = trim((string)$faq_text); 1169 if ($faq_text === '') return []; 1170 $items = []; 1171 $lines = preg_split('/\r\n|\r|\n/', $faq_text); 1172 foreach ($lines as $line) { 1173 $line = trim((string)$line); 1174 if ($line === '' || strpos($line, '|') === false) continue; 1175 $parts = explode('|', $line, 2); 1176 $question = trim($parts[0]); 1177 $answer = isset($parts[1]) ? trim($parts[1]) : ''; 1178 if ($question === '' || $answer === '') continue; 1179 $items[] = [ 1180 '@type' => 'Question', 1181 'name' => $question, 1182 'acceptedAnswer' => [ 1183 '@type' => 'Answer', 1184 'text' => $answer 1185 ] 1186 ]; 1187 } 1188 return $items; 1189 } 1190 private function baiduseo_geo_is_article_schema($type) 1191 { 1192 return is_array($type) ? in_array('Article', $type, true) : $type === 'Article'; 1193 } 1194 private function baiduseo_geo_schema($form, $schema_source, $active_schema_mode, $source_form = []) 1195 { 1196 if ($active_schema_mode === 'custom') { 1197 $custom_schema_json = $this->baiduseo_geo_form_value($form, 'customSchemaJson'); 1198 $custom_schema = json_decode($custom_schema_json, true); 1199 if (!is_array($custom_schema)) return ''; 1200 return '<script type="application/ld+json">' . "\n" . wp_json_encode($custom_schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n" . '</script>' . "\n"; 1201 } 1202 $url = $this->baiduseo_geo_output_value('url', $form, $schema_source, $source_form); 1203 $title = $this->baiduseo_geo_output_value('title', $form, $schema_source, $source_form); 1204 $desc = $this->baiduseo_geo_output_value('desc', $form, $schema_source, $source_form); 1205 $image = $this->baiduseo_geo_output_value('image', $form, $schema_source, $source_form); 1206 $author = $this->baiduseo_geo_output_value('author', $form, $schema_source, $source_form); 1207 $published = $this->baiduseo_geo_output_value('published', $form, $schema_source, $source_form); 1208 $modified = $this->baiduseo_geo_output_value('modified', $form, $schema_source, $source_form); 1209 $schema_type = $this->baiduseo_geo_form_value($form, 'schemaType'); 1210 $company_address = $this->baiduseo_geo_form_value($form, 'companyAddress'); 1211 $org_type = $schema_type === 'LocalBusiness' ? ['Organization', 'LocalBusiness'] : 'Organization'; 1212 $org = [ 1213 '@type' => $org_type, 1214 '@id' => $url ? $url . '#organization' : '', 1215 'name' => $this->baiduseo_geo_form_value($form, 'companyName'), 1216 'url' => $url, 1217 'logo' => $image, 1218 'description' => $desc, 1219 'telephone' => $this->baiduseo_geo_form_value($form, 'phone'), 1220 'email' => $this->baiduseo_geo_form_value($form, 'email'), 1221 'address' => $company_address ? [ 1222 '@type' => 'PostalAddress', 1223 'streetAddress' => $company_address, 1224 'addressCountry' => 'CN' 1225 ] : '', 1226 'sameAs' => $this->baiduseo_geo_same_as($form) 1227 ]; 1228 $website = [ 1229 '@type' => 'WebSite', 1230 '@id' => $url ? $url . '#website' : '', 1231 'url' => $url, 1232 'name' => $title, 1233 'publisher' => ['@id' => $url ? $url . '#organization' : ''] 1234 ]; 1235 $page = [ 1236 '@type' => $this->baiduseo_geo_schema_type($form), 1237 '@id' => $url ? $url . '#webpage' : '', 1238 'url' => $url, 1239 'name' => $title, 1240 'description' => $desc, 1241 'image' => $image, 1242 'isPartOf' => ['@id' => $url ? $url . '#website' : ''] 1243 ]; 1244 if ($this->baiduseo_geo_is_article_schema($page['@type'])) { 1245 $page['headline'] = $title; 1246 $page['author'] = $author ? ['@type' => 'Person', 'name' => $author] : ''; 1247 $page['datePublished'] = $published; 1248 $page['dateModified'] = $modified; 1249 $page['publisher'] = ['@id' => $url ? $url . '#organization' : '']; 1250 $page['mainEntityOfPage'] = ['@type' => 'WebPage', '@id' => $url]; 1251 $page['keywords'] = $this->baiduseo_geo_form_value($form, 'seoKeywords'); 1252 } 1253 if ($page['@type'] === 'FAQPage') { 1254 $page['mainEntity'] = $this->baiduseo_geo_faq_items($this->baiduseo_geo_form_value($form, 'faqText')); 1255 } 1256 $graph = [$org, $website, $page]; 1257 if ($schema_type === 'Service') { 1258 $graph[] = [ 1259 '@type' => 'Service', 1260 '@id' => $url ? $url . '#service' : '', 1261 'name' => $this->baiduseo_geo_form_value($form, 'serviceName') ?: $title, 1262 'description' => $desc, 1263 'provider' => ['@id' => $url ? $url . '#organization' : ''], 1264 'areaServed' => $this->baiduseo_geo_form_value($form, 'areaServed'), 1265 'url' => $url 1266 ]; 1267 } 1268 $schema = $this->baiduseo_geo_strip_empty([ 1269 '@context' => 'https://schema.org', 1270 '@graph' => $graph 1271 ]); 1272 return '<script type="application/ld+json">' . "\n" . wp_json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n" . '</script>' . "\n"; 1273 } 1274 private function baiduseo_geo_output() 1275 { 1276 $config = $this->baiduseo_geo_current_config(); 1277 if (empty($config) || !is_array($config)) return; 1278 $form = isset($config['form']) && is_array($config['form']) ? $config['form'] : []; 1279 $switch = isset($config['switchState']) && is_array($config['switchState']) ? $config['switchState'] : []; 1280 $schema_source = isset($config['schemaSource']) && is_array($config['schemaSource']) ? $config['schemaSource'] : []; 1281 $active_schema_mode = isset($config['activeSchemaMode']) ? $config['activeSchemaMode'] : 'builder'; 1282 $url = $this->baiduseo_geo_output_value('url', $form, $schema_source, $form); 1283 $title = $this->baiduseo_geo_output_value('title', $form, $schema_source, $form); 1284 $desc = $this->baiduseo_geo_output_value('desc', $form, $schema_source, $form); 1285 $image = $this->baiduseo_geo_output_value('image', $form, $schema_source, $form); 1286 $og_image = $this->baiduseo_geo_form_value($form, 'ogImage'); 1287 $twitter_image = $this->baiduseo_geo_form_value($form, 'twitterImage'); 1288 $html = ''; 1289 if ($this->baiduseo_geo_switch_open($switch, 'socialMaster')) { 1290 if ($this->baiduseo_geo_switch_open($switch, 'og')) { 1291 $html .= $this->baiduseo_geo_meta('og:type', $this->baiduseo_geo_form_value($form, 'pageType') === 'article' ? 'article' : 'website', 'property'); 1292 $html .= $this->baiduseo_geo_meta('og:url', $url, 'property'); 1293 $html .= $this->baiduseo_geo_meta('og:title', $title, 'property'); 1294 $html .= $this->baiduseo_geo_meta('og:description', $desc, 'property'); 1295 $html .= $this->baiduseo_geo_meta('og:image', $og_image, 'property'); 1296 } 1297 if ($this->baiduseo_geo_switch_open($switch, 'twitter')) { 1298 $html .= '<meta name="twitter:card" content="summary_large_image">' . "\n"; 1299 $html .= $this->baiduseo_geo_meta('twitter:title', $title); 1300 $html .= $this->baiduseo_geo_meta('twitter:description', $desc); 1301 $html .= $this->baiduseo_geo_meta('twitter:image', $twitter_image); 1302 } 1303 if ($this->baiduseo_geo_switch_open($switch, 'cn')) { 1304 $html .= $this->baiduseo_geo_itemprop('name', $title); 1305 $html .= $this->baiduseo_geo_itemprop('description', $desc); 1306 $html .= $this->baiduseo_geo_itemprop('image', $image); 1307 } 1308 if ($this->baiduseo_geo_switch_open($switch, 'verify')) { 1309 $html .= $this->baiduseo_geo_webmaster_verify_meta(); 1310 $html .= $this->baiduseo_geo_meta('360-site-verification', $this->baiduseo_geo_verify_content($this->baiduseo_geo_form_value($form, 'soVerify'))); 1311 $html .= $this->baiduseo_geo_meta('sogou_site_verification', $this->baiduseo_geo_verify_content($this->baiduseo_geo_form_value($form, 'sogouVerify'))); 1312 $html .= $this->baiduseo_geo_meta('shenma-site-verification', $this->baiduseo_geo_verify_content($this->baiduseo_geo_form_value($form, 'shenmaVerify'))); 1313 } 1314 } 1315 if ($this->baiduseo_geo_switch_open($switch, 'schema')) { 1316 $html .= $this->baiduseo_geo_schema($form, $schema_source, $active_schema_mode, $form); 1317 } 1318 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Meta tags and JSON-LD are assembled by helper methods that escape attributes or encode JSON. 1319 if ($html) echo $html; 941 1320 } 942 1321 public function BaiduSEO_addlink($content) … … 1452 1831 public function baiduseo_enqueue($hook) 1453 1832 { 1454 if ('toplevel_page_baiduseo' != $hook) return; 1455 require plugin_dir_path(BAIDUSEO_FILE) . 'inc/admin/assets.php'; 1456 foreach ($baiduseo_assets as $key => $val) { 1457 if ($val['type'] == 'css') { 1458 wp_enqueue_style($val['name'], plugin_dir_url(BAIDUSEO_FILE) . 'inc/admin/' . $val['url'], array(), BAIDUSEO_VERSION, 'all'); 1459 } elseif ($val['type'] == 'js') { 1460 wp_enqueue_script($val['name'], plugin_dir_url(BAIDUSEO_FILE) . 'inc/admin/' . $val['url'], array(), BAIDUSEO_VERSION, true); 1461 } 1462 } 1463 wp_register_script('baiduseo.js', false, array(), BAIDUSEO_VERSION, false); 1464 wp_enqueue_script('baiduseo.js'); 1465 $url1 = baiduseo_common::baiduseo_url(0); 1466 $baiduseo_yindao = get_option('baiduseo_yindao'); 1467 $baiduseo_yindao = $baiduseo_yindao ? $baiduseo_yindao : 0; 1468 $baiduseo_version = esc_url_raw(admin_url('plugin-install.php?tab=plugin-information&plugin=baiduseo')); 1469 $baiduseo_indexnow = md5(esc_url(baiduseo_common::baiduseo_url(1))); 1470 $baiduseo_aiarticle = esc_url_raw(admin_url('plugin-install.php?tab=plugin-information&plugin=aiarticle')); 1471 $baiduseo_google = baiduseo_common::baiduseo_url(1) . '/wp-sitemap.xml'; 1472 wp_add_inline_script('baiduseo.js', 'var baiduseo_wztkj_url="' . esc_js(plugins_url('', BAIDUSEO_FILE)) . '/inc/admin",baiduseo_nonce="' . esc_attr(wp_create_nonce('baiduseo')) . '",baiduseo_ajax="' . esc_url(admin_url('admin-ajax.php')) . '",baiduseo_tag ="' . esc_url(admin_url('edit-tags.php?taxonomy=post_tag')) . '",baiduseo_url="' . esc_url($url1) . '",baiduseo_yindao=' . (int)$baiduseo_yindao . ',baiduseo_v="' . esc_url($baiduseo_version) . '",baiduseo_indexnow="' . esc_attr($baiduseo_indexnow) . '",baiduseo_google="' . esc_url($baiduseo_google) . '",baiduseo_aiarticle="'.esc_url($baiduseo_aiarticle).'";', 'before'); 1833 if ('toplevel_page_baiduseo' == $hook) { 1834 wp_enqueue_media(); 1835 require plugin_dir_path(BAIDUSEO_FILE) . 'inc/admin/assets.php'; 1836 foreach ($baiduseo_assets as $key => $val) { 1837 if ($val['type'] == 'css') { 1838 wp_enqueue_style($val['name'], plugin_dir_url(BAIDUSEO_FILE) . 'inc/admin/' . $val['url'], array(), BAIDUSEO_VERSION, 'all'); 1839 } elseif ($val['type'] == 'js') { 1840 wp_enqueue_script($val['name'], plugin_dir_url(BAIDUSEO_FILE) . 'inc/admin/' . $val['url'], array(), BAIDUSEO_VERSION, true); 1841 } 1842 } 1843 wp_register_script('baiduseo.js', false, array(), BAIDUSEO_VERSION, false); 1844 wp_enqueue_script('baiduseo.js'); 1845 $url1 = baiduseo_common::baiduseo_url(0); 1846 $baiduseo_yindao = get_option('baiduseo_yindao'); 1847 $baiduseo_yindao = $baiduseo_yindao ? $baiduseo_yindao : 0; 1848 $baiduseo_version = esc_url_raw(admin_url('plugin-install.php?tab=plugin-information&plugin=baiduseo')); 1849 $baiduseo_indexnow = md5(esc_url(baiduseo_common::baiduseo_url(1))); 1850 $baiduseo_aiarticle = esc_url_raw(admin_url('plugin-install.php?tab=plugin-information&plugin=aiarticle')); 1851 $baiduseo_google = baiduseo_common::baiduseo_url(1) . '/wp-sitemap.xml'; 1852 wp_add_inline_script('baiduseo.js', 'var baiduseo_wztkj_url="' . esc_js(plugins_url('', BAIDUSEO_FILE)) . '/inc/admin",baiduseo_nonce="' . esc_attr(wp_create_nonce('baiduseo')) . '",baiduseo_ajax="' . esc_url(admin_url('admin-ajax.php')) . '",baiduseo_tag ="' . esc_url(admin_url('edit-tags.php?taxonomy=post_tag')) . '",baiduseo_url="' . esc_url($url1) . '",baiduseo_yindao=' . (int)$baiduseo_yindao . ',baiduseo_v="' . esc_url($baiduseo_version) . '",baiduseo_indexnow="' . esc_attr($baiduseo_indexnow) . '",baiduseo_google="' . esc_url($baiduseo_google) . '",baiduseo_aiarticle="'.esc_url($baiduseo_aiarticle).'",baiduseo_page_on_front=' . (int)get_option('page_on_front') . ';', 'before'); 1853 return; 1854 } 1855 if (!in_array($hook, ['post.php', 'post-new.php'], true)) return; 1856 $baiduseo_tag = get_option('baiduseo_tag'); 1857 if (!isset($baiduseo_tag['auto']) || (int)$baiduseo_tag['auto'] !== 0) return; 1858 $post_id = isset($_GET['post']) ? (int)$_GET['post'] : 0; 1859 if (!$post_id) return; 1860 $post = get_post($post_id); 1861 if (!$post) return; 1862 $taxonomy = self::baiduseo_get_post_tag_taxonomy($post->post_type); 1863 if (!$taxonomy) return; 1864 $taxonomy_object = get_taxonomy($taxonomy); 1865 wp_enqueue_script('baiduseo-post-tag-recommend', plugin_dir_url(BAIDUSEO_FILE) . 'inc/admin/assets/baiduseo-post-tag-recommend.js', array(), BAIDUSEO_VERSION, true); 1866 wp_add_inline_script('baiduseo-post-tag-recommend', 'window.baiduseoPostTagRecommend=' . wp_json_encode([ 1867 'ajaxUrl' => admin_url('admin-ajax.php'), 1868 'nonce' => wp_create_nonce('baiduseo'), 1869 'postId' => $post_id, 1870 'taxonomy' => $taxonomy, 1871 'restBase' => $taxonomy_object && !empty($taxonomy_object->rest_base) ? $taxonomy_object->rest_base : $taxonomy, 1872 'label' => $taxonomy_object && !empty($taxonomy_object->labels->name) ? $taxonomy_object->labels->name : '标签', 1873 'tagLimit' => self::baiduseo_get_tag_limit($baiduseo_tag), 1874 ]) . ';', 'before'); 1473 1875 } 1474 1876 public function baiduseo_plugin_action_links($links) … … 1554 1956 } 1555 1957 } 1958 private static function baiduseo_get_tag_limit($tag_config) 1959 { 1960 if (!is_array($tag_config) || !isset($tag_config['num'])) { 1961 return 0; 1962 } 1963 $limit = (int)$tag_config['num']; 1964 return $limit > 0 && $limit != 11 ? $limit : 0; 1965 } 1966 public static function baiduseo_get_post_tag_taxonomy($post_type) 1967 { 1968 $taxonomies = get_object_taxonomies($post_type, 'names'); 1969 foreach ($taxonomies as $tax) { 1970 if (!is_taxonomy_hierarchical($tax)) { 1971 return $tax; 1972 } 1973 } 1974 return ''; 1975 } 1976 public static function baiduseo_get_post_tag_recommendations($post_ID, $ignored_ids = [], $content_override = []) 1977 { 1978 global $wpdb; 1979 $post = get_post($post_ID); 1980 if (!$post) { 1981 return []; 1982 } 1983 $current_taxonomy = self::baiduseo_get_post_tag_taxonomy($post->post_type); 1984 if (!$current_taxonomy) { 1985 return []; 1986 } 1987 $tags = $wpdb->get_results($wpdb->prepare( 1988 "SELECT a.term_id,a.name,b.term_taxonomy_id,b.taxonomy,b.count FROM {$wpdb->terms} as a LEFT JOIN {$wpdb->term_taxonomy} as b ON a.term_id=b.term_id WHERE b.taxonomy=%s", 1989 $current_taxonomy 1990 ), ARRAY_A); 1991 if (!$tags) { 1992 return []; 1993 } 1994 $existing_ids = wp_get_object_terms($post_ID, $current_taxonomy, ['fields' => 'ids']); 1995 $existing_ids = is_array($existing_ids) ? array_map('intval', $existing_ids) : []; 1996 $tag_limit = self::baiduseo_get_tag_limit(get_option('baiduseo_tag')); 1997 $remaining_limit = $tag_limit ? $tag_limit - count($existing_ids) : 0; 1998 if ($tag_limit && $remaining_limit <= 0) { 1999 return []; 2000 } 2001 $ignored_ids = is_array($ignored_ids) ? array_map('intval', $ignored_ids) : []; 2002 $title = isset($content_override['title']) ? sanitize_text_field(wp_unslash($content_override['title'])) : $post->post_title; 2003 $content = isset($content_override['content']) ? wp_kses_post(wp_unslash($content_override['content'])) : $post->post_content; 2004 $plain_content = wp_strip_all_tags(strip_shortcodes($content)); 2005 $plain_length = mb_strlen($plain_content, 'UTF-8'); 2006 $front_content = $plain_length ? mb_substr($plain_content, 0, (int)ceil($plain_length * 0.3), 'UTF-8') : ''; 2007 $headings = self::baiduseo_get_post_tag_heading_text($content); 2008 $recent_terms = self::baiduseo_get_recent_post_tag_usage(array_column($tags, 'term_taxonomy_id')); 2009 usort($tags, function ($a, $b) { 2010 return (int)$b['count'] <=> (int)$a['count']; 2011 }); 2012 $total_tags = count($tags); 2013 $top_limit = (int)ceil($total_tags * 0.2); 2014 $middle_limit = (int)ceil($total_tags * 0.5); 2015 $normalized_seen = []; 2016 $recommendations = []; 2017 foreach ($tags as $index => $tag) { 2018 $term_id = (int)$tag['term_id']; 2019 if (in_array($term_id, $existing_ids, true) || in_array($term_id, $ignored_ids, true)) { 2020 continue; 2021 } 2022 $name = isset($tag['name']) ? trim((string)$tag['name']) : ''; 2023 if (!self::baiduseo_is_valid_post_tag_candidate($name)) { 2024 continue; 2025 } 2026 $normalized_name = self::baiduseo_normalize_post_tag_name($name); 2027 if (!$normalized_name || isset($normalized_seen[$normalized_name])) { 2028 continue; 2029 } 2030 $content_score = 0; 2031 $reasons = []; 2032 if (self::baiduseo_post_tag_text_contains($title, $name)) { 2033 $content_score += 60; 2034 $reasons[] = '标题命中'; 2035 } 2036 if (self::baiduseo_post_tag_text_contains($front_content, $name)) { 2037 $content_score += 30; 2038 $reasons[] = '正文前段命中'; 2039 } 2040 if (self::baiduseo_post_tag_text_contains($headings, $name)) { 2041 $content_score += 20; 2042 $reasons[] = '正文标题命中'; 2043 } 2044 if (!$content_score && !self::baiduseo_post_tag_text_contains($plain_content, $name)) { 2045 continue; 2046 } 2047 $length_score = self::baiduseo_get_post_tag_length_score($name); 2048 $activity_score = 0; 2049 if ($index < $top_limit) { 2050 $activity_score = 10; 2051 $reasons[] = '热门标签'; 2052 } elseif ($index < $middle_limit) { 2053 $activity_score = 5; 2054 $reasons[] = '活跃标签'; 2055 } 2056 $count = (int)$tag['count']; 2057 if ($count <= 1 && empty($recent_terms[(int)$tag['term_taxonomy_id']])) { 2058 $activity_score -= 5; 2059 $reasons[] = '低活跃降权'; 2060 } 2061 $score = $content_score + $length_score + $activity_score; 2062 $normalized_seen[$normalized_name] = true; 2063 $recommendations[] = [ 2064 'term_id' => $term_id, 2065 'term_taxonomy_id' => (int)$tag['term_taxonomy_id'], 2066 'name' => $name, 2067 'taxonomy' => $tag['taxonomy'], 2068 'score' => $score, 2069 'content_score' => $content_score, 2070 'count' => $count, 2071 'length' => mb_strlen($name, 'UTF-8'), 2072 'reasons' => $reasons 2073 ]; 2074 } 2075 usort($recommendations, function ($a, $b) { 2076 if ($a['score'] !== $b['score']) return $b['score'] <=> $a['score']; 2077 if ($a['content_score'] !== $b['content_score']) return $b['content_score'] <=> $a['content_score']; 2078 if ($a['count'] !== $b['count']) return $b['count'] <=> $a['count']; 2079 if ($a['length'] !== $b['length']) return $b['length'] <=> $a['length']; 2080 return $a['term_id'] <=> $b['term_id']; 2081 }); 2082 $recommendations = array_map(function ($tag) { 2083 unset($tag['content_score'], $tag['count'], $tag['length']); 2084 return $tag; 2085 }, $recommendations); 2086 return array_slice($recommendations, 0, $tag_limit ? $remaining_limit : 15); 2087 } 2088 private static function baiduseo_normalize_post_tag_name($name) 2089 { 2090 $name = trim(wp_strip_all_tags((string)$name)); 2091 $name = preg_replace('/\s+/u', ' ', $name); 2092 return function_exists('mb_strtolower') ? mb_strtolower($name, 'UTF-8') : strtolower($name); 2093 } 2094 private static function baiduseo_is_valid_post_tag_candidate($name) 2095 { 2096 $name = trim((string)$name); 2097 if ($name === '' || mb_strlen($name, 'UTF-8') > 80) { 2098 return false; 2099 } 2100 if ($name !== wp_strip_all_tags($name) || preg_match('/[\x00-\x1F\x7F]/u', $name)) { 2101 return false; 2102 } 2103 $text = preg_replace('/[\p{Han}\p{L}\p{N}]/u', '', $name); 2104 return mb_strlen($text, 'UTF-8') < mb_strlen($name, 'UTF-8'); 2105 } 2106 private static function baiduseo_post_tag_text_contains($text, $term) 2107 { 2108 $text = self::baiduseo_normalize_post_tag_name($text); 2109 $term = self::baiduseo_normalize_post_tag_name($term); 2110 if ($text === '' || $term === '') { 2111 return false; 2112 } 2113 return mb_strpos($text, $term, 0, 'UTF-8') !== false; 2114 } 2115 private static function baiduseo_get_post_tag_length_score($name) 2116 { 2117 $length = mb_strlen($name, 'UTF-8'); 2118 if ($length >= 9) return 15; 2119 if ($length >= 5) return 10; 2120 if ($length >= 3) return 5; 2121 return 0; 2122 } 2123 private static function baiduseo_get_post_tag_heading_text($content) 2124 { 2125 if (!preg_match_all('/<h[23][^>]*>(.*?)<\/h[23]>/is', $content, $matches)) { 2126 return ''; 2127 } 2128 return wp_strip_all_tags(implode(' ', $matches[1])); 2129 } 2130 private static function baiduseo_get_recent_post_tag_usage($term_taxonomy_ids) 2131 { 2132 global $wpdb; 2133 $term_taxonomy_ids = array_values(array_filter(array_map('intval', $term_taxonomy_ids))); 2134 if (!$term_taxonomy_ids) { 2135 return []; 2136 } 2137 $placeholders = implode(',', array_fill(0, count($term_taxonomy_ids), '%d')); 2138 $since = gmdate('Y-m-d H:i:s', current_time('timestamp') - 90 * DAY_IN_SECONDS); 2139 $rows = $wpdb->get_results($wpdb->prepare( 2140 "SELECT tr.term_taxonomy_id,COUNT(*) as total FROM {$wpdb->term_relationships} tr INNER JOIN {$wpdb->posts} p ON tr.object_id=p.ID WHERE tr.term_taxonomy_id IN ($placeholders) AND p.post_status='publish' AND p.post_date >= %s GROUP BY tr.term_taxonomy_id", 2141 array_merge($term_taxonomy_ids, [$since]) 2142 ), ARRAY_A); 2143 $usage = []; 2144 foreach ($rows as $row) { 2145 $usage[(int)$row['term_taxonomy_id']] = (int)$row['total']; 2146 } 2147 return $usage; 2148 } 1556 2149 public function baiduseo_articlepublish($post_ID) 1557 2150 { 1558 global $wpdb;1559 2151 $baiduseo_wzt_log = baiduseo_kp::baiduseo_wzt_log(); 1560 // 1. 基础检查1561 2152 if (!$baiduseo_wzt_log) { 1562 2153 return; 1563 2154 } 1564 1565 // 2. 获取文章对象和类型,为动态处理做准备 2155 $baiduseo_tag = get_option('baiduseo_tag'); 2156 if (!isset($baiduseo_tag['auto']) || (int)$baiduseo_tag['auto'] !== 1) { 2157 return; 2158 } 1566 2159 $post = get_post($post_ID); 1567 2160 if (!$post) { 1568 return; // 如果文章不存在,则退出1569 }1570 $post_type = $post->post_type;1571 $post_content = $post->post_content;1572 1573 // 3. 动态获取当前文章类型支持的“标签”分类法 (非层级分类法)1574 $taxonomies = get_object_taxonomies($post_type, 'names');1575 $tag_taxonomies = '';1576 foreach ($taxonomies as $tax) {1577 if (!is_taxonomy_hierarchical($tax)) {1578 $tag_taxonomies = $tax;1579 break;1580 }1581 }1582 1583 // 如果该文章类型没有任何标签分类法,则无需继续执行1584 if (!$tag_taxonomies) {1585 2161 return; 1586 2162 } 1587 $current_taxonomy = $tag_taxonomies; 1588 1589 // 4. 读取插件设置 1590 $baiduseo_tag = get_option('baiduseo_tag'); 1591 1592 // 准备标签列表(根据设置排序) 2163 $current_taxonomy = self::baiduseo_get_post_tag_taxonomy($post->post_type); 2164 if (!$current_taxonomy) { 2165 return; 2166 } 2167 global $wpdb; 1593 2168 if (isset($baiduseo_tag['pp']) && $baiduseo_tag['pp'] == 1) { 1594 $tags = $wpdb->get_results('SELECT * FROM ' . $wpdb->prefix . 'terms ORDER BY LENGTH(name) DESC', ARRAY_A); 2169 $tags = $wpdb->get_results( 2170 $wpdb->prepare( 2171 'SELECT a.term_id,a.name,b.term_taxonomy_id,b.taxonomy FROM ' . $wpdb->prefix . 'terms as a left join ' . $wpdb->prefix . 'term_taxonomy as b on a.term_id=b.term_id where b.taxonomy=%s ORDER BY LENGTH(a.name) DESC', 2172 $current_taxonomy 2173 ), 2174 ARRAY_A 2175 ); 1595 2176 } elseif (isset($baiduseo_tag['pp']) && $baiduseo_tag['pp'] == 2) { 1596 $tags = $wpdb->get_results('SELECT * FROM ' . $wpdb->prefix . 'terms ORDER BY LENGTH(name) ASC', ARRAY_A); 2177 $tags = $wpdb->get_results( 2178 $wpdb->prepare( 2179 'SELECT a.term_id,a.name,b.term_taxonomy_id,b.taxonomy FROM ' . $wpdb->prefix . 'terms as a left join ' . $wpdb->prefix . 'term_taxonomy as b on a.term_id=b.term_id where b.taxonomy=%s ORDER BY LENGTH(a.name) ASC', 2180 $current_taxonomy 2181 ), 2182 ARRAY_A 2183 ); 1597 2184 } else { 1598 $tags = $wpdb->get_results('SELECT * FROM ' . $wpdb->prefix . 'terms', ARRAY_A); 1599 } 1600 1601 // 性能优化:提前准备好正则表达式的模式 2185 $tags = $wpdb->get_results( 2186 $wpdb->prepare( 2187 'SELECT a.term_id,a.name,b.term_taxonomy_id,b.taxonomy FROM ' . $wpdb->prefix . 'terms as a left join ' . $wpdb->prefix . 'term_taxonomy as b on a.term_id=b.term_id where b.taxonomy=%s', 2188 $current_taxonomy 2189 ), 2190 ARRAY_A 2191 ); 2192 } 2193 if (!$tags) { 2194 return; 2195 } 1602 2196 $hremove_regex = isset($baiduseo_tag['hremove']) && $baiduseo_tag['hremove'] == 1; 1603 1604 // 5. 执行标签添加逻辑 1605 // 情况A:不限制标签数量,或数量设置为11 1606 if (!isset($baiduseo_tag['num']) || !$baiduseo_tag['num'] || $baiduseo_tag['num'] == 11) { 1607 foreach ($tags as $v) { 1608 // 检查该术语是否属于当前文章类型的标签分类法 1609 $term_in_tax = $wpdb->get_var($wpdb->prepare( 1610 "SELECT COUNT(*) FROM {$wpdb->prefix}term_taxonomy WHERE taxonomy = %s AND term_id = %d", 1611 $current_taxonomy, 1612 $v['term_id'] 2197 $max_tags = self::baiduseo_get_tag_limit($baiduseo_tag); 2198 if ($max_tags) { 2199 $current_count = (int)$wpdb->get_var($wpdb->prepare( 2200 "SELECT COUNT(*) FROM {$wpdb->prefix}term_relationships tr INNER JOIN {$wpdb->prefix}term_taxonomy tt ON tr.term_taxonomy_id=tt.term_taxonomy_id WHERE tr.object_id=%d AND tt.taxonomy=%s", 2201 $post_ID, 2202 $current_taxonomy 2203 )); 2204 if ($current_count >= $max_tags) { 2205 return; 2206 } 2207 } 2208 foreach ($tags as $tag) { 2209 $term_regex = baiduseo_tag::BaiduSEO_preg($tag['name']); 2210 if ($hremove_regex) { 2211 $pattern = '{(?!((<.*?)|(<a.*?)|(<h[1-6].*?>)))(' . $term_regex . ')(?!(([^<>]*?)>)|([^>]*?</a>)|([^>]*?</h[1-6]>))}i'; 2212 } else { 2213 $pattern = '{(?!((<.*?)|(<a.*?)))(' . $term_regex . ')(?!(([^<>]*?)>)|([^>]*?</a>))}i'; 2214 } 2215 if (preg_match($pattern, $post->post_content)) { 2216 $is_attached = $wpdb->get_var($wpdb->prepare( 2217 "SELECT COUNT(*) FROM {$wpdb->prefix}term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", 2218 $post_ID, 2219 $tag['term_taxonomy_id'] 1613 2220 )); 1614 if (!$term_in_tax) { 1615 continue; 1616 } 1617 1618 // 构建正则表达式 1619 $term_regex = baiduseo_tag::BaiduSEO_preg($v['name']); 1620 if ($hremove_regex) { 1621 $pattern = '{(?!((<.*?)|(<a.*?)|(<h[1-6].*?>)))(' . $term_regex . ')(?!(([^<>]*?)>)|([^>]*?<\/a>)|([^>]*?<\/h[1-6]>))}i'; 1622 } else { 1623 $pattern = '{(?!((<.*?)|(<a.*?)))(' . $term_regex . ')(?!(([^<>]*?)>)|([^>]*?<\/a>))}i'; 1624 } 1625 1626 if (preg_match($pattern, $post_content, $matches)) { 1627 // 获取 term_taxonomy_id 1628 $tt_id = $wpdb->get_var($wpdb->prepare( 1629 "SELECT term_taxonomy_id FROM {$wpdb->prefix}term_taxonomy WHERE taxonomy = %s AND term_id = %d", 1630 $current_taxonomy, 1631 $v['term_id'] 2221 if (!$is_attached) { 2222 $wpdb->insert($wpdb->prefix . "term_relationships", [ 2223 'object_id' => $post_ID, 2224 'term_taxonomy_id' => $tag['term_taxonomy_id'] 2225 ]); 2226 $wpdb->query($wpdb->prepare( 2227 "UPDATE {$wpdb->prefix}term_taxonomy SET count = count + 1 WHERE term_taxonomy_id = %d", 2228 $tag['term_taxonomy_id'] 1632 2229 )); 1633 1634 if ($tt_id) { 1635 // 检查该标签是否已与文章关联 1636 $is_attached = $wpdb->get_var($wpdb->prepare( 1637 "SELECT COUNT(*) FROM {$wpdb->prefix}term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", 1638 $post_ID, 1639 $tt_id 1640 )); 1641 if (!$is_attached) { 1642 // 添加关联 1643 $wpdb->insert($wpdb->prefix . "term_relationships", [ 1644 'object_id' => $post_ID, 1645 'term_taxonomy_id' => $tt_id 1646 ]); 1647 // 更新计数 1648 $wpdb->query($wpdb->prepare( 1649 "UPDATE {$wpdb->prefix}term_taxonomy SET count = count + 1 WHERE term_taxonomy_id = %d", 1650 $tt_id 1651 )); 1652 } 1653 } 1654 } 1655 } 1656 } 1657 // 情况B:限制标签数量 1658 else { 1659 $max_tags = (int)$baiduseo_tag['num']; 1660 // 获取当前文章已有的标签数量 1661 $existing_terms_count = wp_get_object_terms($post_ID, $current_taxonomy, array('fields' => 'ids')); 1662 $existing_terms_count = is_array($existing_terms_count) ? count($existing_terms_count) : 0; 1663 1664 if ($existing_terms_count < $max_tags) { 1665 foreach ($tags as $v) { 1666 // 如果已达到标签数量上限,则停止循环 1667 if ($existing_terms_count >= $max_tags) { 1668 break; 1669 } 1670 1671 // 检查该术语是否属于当前文章类型的标签分类法 1672 $term_in_tax = $wpdb->get_var($wpdb->prepare( 1673 "SELECT COUNT(*) FROM {$wpdb->prefix}term_taxonomy WHERE taxonomy = %s AND term_id = %d", 1674 $current_taxonomy, 1675 $v['term_id'] 1676 )); 1677 if (!$term_in_tax) { 1678 continue; 1679 } 1680 1681 // 构建正则表达式 1682 $term_regex = baiduseo_tag::BaiduSEO_preg($v['name']); 1683 if ($hremove_regex) { 1684 $pattern = '{(?!((<.*?)|(<a.*?)|(<h[1-6].*?>)))(' . $term_regex . ')(?!(([^<>]*?)>)|([^>]*?<\/a>)|([^>]*?<\/h[1-6]>))}i'; 1685 } else { 1686 $pattern = '{(?!((<.*?)|(<a.*?)))(' . $term_regex . ')(?!(([^<>]*?)>)|([^>]*?<\/a>))}i'; 1687 } 1688 1689 if (preg_match($pattern, $post_content, $matches)) { 1690 // 获取 term_taxonomy_id 1691 $tt_id = $wpdb->get_var($wpdb->prepare( 1692 "SELECT term_taxonomy_id FROM {$wpdb->prefix}term_taxonomy WHERE taxonomy = %s AND term_id = %d", 1693 $current_taxonomy, 1694 $v['term_id'] 1695 )); 1696 1697 if ($tt_id) { 1698 // 检查该标签是否已与文章关联 1699 $is_attached = $wpdb->get_var($wpdb->prepare( 1700 "SELECT COUNT(*) FROM {$wpdb->prefix}term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", 1701 $post_ID, 1702 $tt_id 1703 )); 1704 if (!$is_attached) { 1705 // 添加关联 1706 $wpdb->insert($wpdb->prefix . "term_relationships", [ 1707 'object_id' => $post_ID, 1708 'term_taxonomy_id' => $tt_id 1709 ]); 1710 // 更新计数 1711 $wpdb->query($wpdb->prepare( 1712 "UPDATE {$wpdb->prefix}term_taxonomy SET count = count + 1 WHERE term_taxonomy_id = %d", 1713 $tt_id 1714 )); 1715 // 更新已添加标签计数 1716 $existing_terms_count++; 1717 } 2230 if ($max_tags) { 2231 $current_count++; 2232 if ($current_count >= $max_tags) { 2233 break; 1718 2234 } 1719 2235 } -
baiduseo/trunk/readme.txt
r3551508 r3625549 1 === SEO合集(支持百度/Google/Bing/ 头条推送) ===1 === SEO合集(支持百度/Google/Bing/geo优化) === 2 2 Donate link: https://www.seoceo.cn 3 Tags: seo, 百度, google, sitemap, 蜘蛛3 Tags: seo, geo, google, sitemap, 蜘蛛 4 4 Requires at least: 5.3 5 5 Tested up to: 7.0 6 Stable tag: 2.2. 16 Stable tag: 2.2.2 7 7 Requires PHP: 7.4 8 8 License: GPLv3 9 9 License URI: https://www.gnu.org/licenses/gpl-3.0.html 10 10 11 支持百度(baidu)、谷歌google、Bing、indexNow、sitemap地图、robots、TDK关键词部署、img图片alt/title属性、网站蜘蛛、网站SEO检测评分、WP优化、tag内链关键词自动关联、词库挖掘、热词库创建、友情链接户换、流量监控、访客明细、AI自动发文章等。11 WordPress SEO插件和站长工具,支持百度推送、收录查询、Sitemap网站地图、robots优化、蜘蛛日志、IndexNow推送、内链优化、关键词监控和geo优化。 12 12 13 13 == Description == … … 15 15 SEO合集是一款面向中文网站、WordPress站长、企业官网、博客站、资讯站、内容站和SEO团队的WordPress SEO插件。插件适合用于seo优化、网站SEO优化、seo网站建设、WordPress SEO优化、中文SEO优化、站长SEO工具、网站SEO工具和SEO工具箱等场景,帮助站长在一个后台中完成搜索引擎推送、收录查询、网站地图、蜘蛛日志、站内内链、关键词排名监控和内容优化等工作。 16 16 17 SEO合集围绕国内站长常用的搜索引擎优化需求开发,整合百度站长、百度推送、百度主动推送、百度自动推送、百度URL提交、百度收录查询、百度快速收录、Google站长、Google Indexing、Bing站长、Bing IndexNow、360站长、神马站长、今日头条站长、Sitemap网站地图、XML地图、HTML地图、robots.txt、网站蜘蛛、蜘蛛日志、站内内链、tag标签内链、关键词排名监控、流量词获取、图片Alt标签、301重定向、404监控、死链查询、原创率检测、 AI文章助手和智能改写等功能。17 SEO合集围绕国内站长常用的搜索引擎优化需求开发,整合百度站长、百度推送、百度主动推送、百度自动推送、百度URL提交、百度收录查询、百度快速收录、Google站长、Google Indexing、Bing站长、Bing IndexNow、360站长、神马站长、今日头条站长、Sitemap网站地图、XML地图、HTML地图、robots.txt、网站蜘蛛、蜘蛛日志、站内内链、tag标签内链、关键词排名监控、流量词获取、图片Alt标签、301重定向、404监控、死链查询、原创率检测、geo、AI文章助手和智能改写等功能。 18 18 19 19 = SEO基础、SEO优化和WordPress SEO插件 = … … 84 84 85 85 SEO合集还包含友情链接、友情链接检测、SEO检测、WP优化、流量监控和用户漏洞修复等功能。友情链接检测适合需要维护交换链接的网站,SEO检测和WP优化适合站长日常检查网站基础优化情况,用户漏洞修复功能用于辅助处理WordPress站点常见安全风险。 86 = GEO生成式引擎优化、AI搜索优化和ChatGPT收录 = 87 88 GEO合集主要面向国内中文网站、WordPress网站和WordPress站长,提供GEO优化、生成式引擎优化、生成引擎优化、AI搜索优化、AI SEO优化、AEO答案引擎优化、ChatGPT SEO、ChatGPT优化、ChatGPT收录、ChatGPT推荐、AI收录、AI引用、AI排名、AI推荐和AI品牌曝光等相关能力。 89 90 相关功能适用于希望提升网站在ChatGPT、DeepSeek、豆包、腾讯元宝、Kimi、文心一言、通义千问、百度AI搜索、360AI搜索、Google AI Overview、Bing Copilot、Gemini、Claude和Perplexity等AI搜索引擎、AI问答平台、生成式搜索和大模型平台中曝光度的中文网站。 91 92 插件可以帮助WordPress网站优化文章标题、正文结构、FAQ问答、内容摘要、语义信息、实体信息、结构化数据和llms.txt文件,让AI搜索引擎、生成式引擎和大语言模型更容易抓取、理解、收录、引用和推荐网站内容。通过WordPress GEO、AI SEO、AEO和传统SEO协同优化,提高网站页面在AI搜索结果、生成式回答和大模型答案中的可见性、引用率、推荐机会和品牌曝光。 86 93 87 94 这些功能与百度站长、Google站长、Bing站长、Sitemap网站地图、网站蜘蛛、站内内链、关键词排名监控、原创率检测和AI文章助手共同组成SEO合集的综合工具面板。 … … 209 216 插件部分功能需要第三方授权或接口服务支持。请在使用前阅读服务协议和隐私政策,并根据自身网站需求选择开启相关功能。 210 217 218 219 211 220 == Changelog == 212 213 == Changelog == 221 = 2.2.2 =(2026/07/28) 222 *新增geo功能 223 *修复已知BUG 224 *优化部分功能的实现方式 225 *全局安全更新 214 226 = 2.2.1 =(2026/04/08) 215 227 *修复流量监控不统计问题 -
baiduseo/trunk/seo_title_baidu.php
r3501273 r3625549 3 3 Plugin Name: SEO合集(支持百度/Google/Bing/头条推送) 4 4 Description: 含百度站长、360站长、Bing站长、今日头条站长、神马站长、IndexNow、tag标签内链、友情链接、百度地图sitemap、Google地图、 谷歌地图、关键词排名查询监控、360站长JS自动推送、 文章原创率检测、文章伪原创、 网站蜘蛛、robots、图片alt标签、天级推送、category隐藏、死链查询、百度自动推送、批量提交URL到站长、百度收录查询、批量推送未收录、301/404等功能、AI文章助手、流量监控。 5 Version: 2.2. 15 Version: 2.2.2 6 6 Author: 沃之涛科技 7 7 Author URI: https://www.seoceo.cn … … 10 10 */ 11 11 if(!defined('ABSPATH'))exit; 12 define('BAIDUSEO_VERSION','2.2. 1');12 define('BAIDUSEO_VERSION','2.2.2'); 13 13 define('BAIDUSEO_FILE',__FILE__); 14 14 define('BAIDUSEO_NAME',plugin_basename(__FILE__));
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)