├── README.md └── Sitemap ├── Sitemap.php ├── Plugin.php └── Action.php /README.md: -------------------------------------------------------------------------------- 1 | # Sitemap 文档地址 2 | # https://oct.cn/view/66 3 | -------------------------------------------------------------------------------- /Sitemap/Sitemap.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 网站地图 - <?php echo $this->Options->title ?> 15 | 67 | 68 | 69 | 70 |

Options->title ?> SiteMap

71 | 72 |
73 | Sitemap->postChangefreq != 'none') { ?> 74 |
75 |

文章

76 | 83 |
84 | 85 | Sitemap->pagesChangefreq != 'none') { ?> 86 |
87 |

独立页面

88 | 95 |
96 | 97 | Sitemap->cateChangefreq != 'none') { ?> 98 |
99 |

分类页面

100 | 107 |
108 | 109 | Sitemap->tagChangefreq != 'none') { ?> 110 |
111 |

标签页面

112 | 119 |
120 | 121 | Sitemap->HomePageChangefreq != 'none') { ?> 122 |
123 |

总页数

124 | 131 |
132 | 133 |
134 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /Sitemap/Plugin.php: -------------------------------------------------------------------------------- 1 | Sitemap.xml、Sitemap.html百度自动推送API手动推送
4 | * 设置教程请访问:教程地址>> 5 | * 6 | * @package Sitemap 7 | * @author 十月 Oct.cn 8 | * @version 1.1.1 9 | * @link https://Oct.cn/view/66 10 | */ 11 | 12 | class Sitemap_Plugin implements Typecho_Plugin_Interface 13 | { 14 | /** 15 | * 激活插件方法,如果激活失败,直接抛出异常 16 | * 17 | * @access public 18 | * @return String 19 | * @throws Typecho_Plugin_Exception 20 | */ 21 | public static function activate() 22 | { 23 | /*检测路由*/ 24 | $options = Typecho_Widget::widget('Widget_Options'); 25 | $check = 0; 26 | $retmsg = '开启成功, 插件已经成功激活!请设置主动推送地址'; 27 | foreach ($options->routingTable as $v) { 28 | if (($v['url'] == '/sitemap.xml' || strpos($v['url'], 'sitemap.xml')) && $v['widget'] != 'Sitemap_Action') { 29 | $check = 1; 30 | break; 31 | } 32 | } 33 | if ($check === 1) { 34 | $retmsg = '开启成功,插件路由被占用。sitemap.xml若无法正确使用,请禁用其他相关插件'; 35 | } 36 | Helper::addRoute('sitemap', '/sitemap.xml', 'Sitemap_Action', 'siteMap'); 37 | Helper::addRoute('sitemap.html', '/sitemap.html', 'Sitemap_Action', 'sitemaphtml'); 38 | Helper::addRoute('sitemap/gateway_[key]', '/sitemap/gateway_[key]', 'Sitemap_Action', 'siteName'); 39 | Helper::addRoute('sitemap/sitemap_[key]', '/sitemap/sitemap_[key].xml', 'Sitemap_Action', 'siteList'); 40 | Helper::addRoute('sitemap/sitemap_[key]_[page]', '/sitemap/sitemap_[key]_[page].xml', 'Sitemap_Action', 'siteList'); 41 | Typecho_Plugin::factory('Widget_Contents_Post_Edit')->finishPublish = array(__CLASS__, 'render'); 42 | return ($retmsg); 43 | } 44 | /** 45 | * 禁用插件方法,如果禁用失败,直接抛出异常 46 | * 47 | * @static 48 | * @access public 49 | * @return String 50 | * @throws Typecho_Plugin_Exception 51 | */ 52 | public static function deactivate() 53 | { 54 | Helper::removeRoute('sitemap'); 55 | Helper::removeAction('sitemap.html'); 56 | Helper::removeAction('sitemap/gateway_[key]'); 57 | Helper::removeAction('sitemap/sitemap_[key]'); 58 | Helper::removeAction('sitemap/sitemap_[key]_[page]'); 59 | return ('插件已禁用'); 60 | } 61 | /** 62 | * 获取插件配置面板 63 | * 64 | * @access public 65 | * @param Typecho_Widget_Helper_Form $form 配置面板 66 | * @return void 67 | */ 68 | public static function config(Typecho_Widget_Helper_Form $form) 69 | { 70 | $siteStatus = new Typecho_Widget_Helper_Form_Element_Radio('siteStatus', array('1' => _t('开启'), '0' => _t('关闭')), '1', _t('开启sitemap.xml'), _t('开启后对收录更友好')); 71 | $form->addInput($siteStatus); 72 | $baiduPost = new Typecho_Widget_Helper_Form_Element_Radio('baiduPost', array('1' => _t('开启'), '0' => _t('关闭')), '1', _t('开启自动推送'), _t('开启后发布完文章会自动推送文章地址给百度,加快收录。主动推送说明')); 73 | $form->addInput($baiduPost); 74 | $apiUrl = new Typecho_Widget_Helper_Form_Element_Text('apiUrl', NULL, '', _t('百度推送接口地址'), _t('token变化后,请同步修改此处,否则身份校验不通过将推送失败。获取地址教程')); 75 | $form->addInput($apiUrl); 76 | $apiPostToken = new Typecho_Widget_Helper_Form_Element_Text('apiPostToken', NULL, null, _t('API推送密钥'), _t('设置一个密钥,使用api推送时需携带,确保api安全调用。请勿外泄。使用说明'), ['class' => 'mini']); 77 | $apiPostToken->input->setAttribute('class', 'mini'); 78 | $form->addInput($apiPostToken); 79 | // 隐藏的分类 80 | $mid = new Typecho_Widget_Helper_Form_Element_Text('mid', NULL, null, _t('填写不显示的分类mid'), _t('多个请用英文逗号,隔开。如:1,2 设置后将不输出该分类下的文章。mid获取方式:点击分类->编辑->查看网址后面的mid数字'), ['class' => 'mini']); 81 | $mid->input->setAttribute('class', 'mini'); 82 | $form->addInput($mid); 83 | // 分级 由于百度已取消对二级sitemap支持 该功能已无效果 84 | $congifPriority = new Typecho_Widget_Helper_Layout('div', array('class=' => 'typecho-page-title')); 85 | $congifPriority->html('

分级设置

'); 86 | $congifPriority->setAttribute('style', 'border-bottom:solid 1px #cfcfcf'); 87 | $form->addItem($congifPriority); 88 | $levelSite = new Typecho_Widget_Helper_Form_Element_Radio('levelSite', array('1' => _t('不开启分级'), '0' => _t('开启分级')), '1', _t('是否分多个xml文件'), _t('百度不再收录分级,该功能已取消。设置不生效')); 89 | $form->addInput($levelSite); 90 | $sitePageSize = new Typecho_Widget_Helper_Form_Element_Radio('sitePageSize', array('200' => _t('200'), '500' => _t('500'), '1000' => _t('1000'), '2000' => _t('2000'), '5000' => _t('5000'), '10000' => _t('10000')), '500', _t('文章最多可显示多少条'), _t('数量越大加载sitemap.xml耗时越大,建议500条,优先显示最新')); 91 | $form->addInput($sitePageSize); 92 | // 优先级 93 | $congifPriority = new Typecho_Widget_Helper_Layout('div', array('class=' => 'typecho-page-title')); 94 | $congifPriority->html('

优先级、更新频率、显示控制

'); 95 | $congifPriority->setAttribute('style', 'border-bottom:solid 1px #cfcfcf'); 96 | $form->addItem($congifPriority); 97 | // 分类 98 | Sitemap_Plugin::_addInput($form, 'cate', '分类页', 'always', '0.9'); 99 | // 标签 100 | Sitemap_Plugin::_addInput($form, 'tag', '标签页', 'always', '0.8'); 101 | // 文章页 102 | Sitemap_Plugin::_addInput($form, 'post', '文章页', 'weekly', '0.9'); 103 | // 独立页面 104 | Sitemap_Plugin::_addInput($form, 'pages', '独立页', 'monthly', '0.8'); 105 | // 搜索结果页 106 | Sitemap_Plugin::_addInput($form, 'search', '搜索结果页', 'weekly', '0.8'); 107 | // 首页翻页 108 | Sitemap_Plugin::_addInput($form, 'HomePage', '首页翻页', 'weekly', '0.8'); 109 | // 分类翻页 110 | Sitemap_Plugin::_addInput($form, 'CatePage', '分类翻页', 'monthly', '0.7'); 111 | } 112 | /** 113 | * 个人用户的配置面板 114 | * 115 | * @access public 116 | * @param Typecho_Widget_Helper_Form $form 117 | * @return void 118 | */ 119 | public static function personalConfig(Typecho_Widget_Helper_Form $form) 120 | { 121 | } 122 | /** 123 | * 插件实现方法 124 | * 125 | * @access public 126 | * @return void 127 | */ 128 | public static function render($contents, $widget) 129 | { 130 | $options = Typecho_Widget::widget('Widget_Options'); 131 | $Sitemap = $options->Plugin('Sitemap'); 132 | /* 允许自动推送 */ 133 | if ($Sitemap->baiduPost == 1) { 134 | $url = $widget->permalink; 135 | $mid = Typecho_Widget::widget('Sitemap_Action')->_ckmid(); 136 | if (in_array($widget->categories[0]['mid'], $mid)) { 137 | $postMsg = '该分类设置了隐藏,不主动推送'; 138 | } else { 139 | $res = Typecho_Widget::widget('Sitemap_Action')->sendBaiduPost($url); 140 | $postMsg = $res['msg']; 141 | } 142 | $adminUrl = Typecho_Common::url('manage-posts.php', $options->adminUrl); 143 | header("refresh:0;url= " . $adminUrl); 144 | Typecho_Widget::widget('Widget_Notice')->set(_t('文章 "%s" 已经发布 ' . $postMsg, $url, $widget->title), 'success'); 145 | die(); 146 | } 147 | } 148 | /** 149 | * 封装方法 150 | */ 151 | private static function _addInput($form, $name, $title, $changefreq, $priority) 152 | { 153 | $c = array( 154 | 'none' => _t('不显示'), 155 | 'always' => _t('always(经常)'), 156 | 'daily' => _t('daily(每天)'), 157 | 'weekly' => _t('weekly(每周)'), 158 | 'monthly' => _t('monthly(每月)'), 159 | 'yearly' => _t('yearly(每年)'), 160 | 'hourly' => _t('hourly(每时)') 161 | ); 162 | $p = array( 163 | '1' => _t('1'), 164 | '0.9' => _t('0.9'), 165 | '0.8' => _t('0.8'), 166 | '0.7' => _t('0.7'), 167 | '0.6' => _t('0.6'), 168 | '0.5' => _t('0.5') 169 | ); 170 | $Select = new Typecho_Widget_Helper_Form_Element_Select($name . 'Changefreq', $c, $changefreq, _t('' . $title . '')); 171 | $Select->label->setAttribute('class', ''); 172 | $form->addInput($Select); 173 | $Radio = new Typecho_Widget_Helper_Form_Element_Radio($name . 'Priority', $p, $priority); 174 | $form->addInput($Radio); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Sitemap/Action.php: -------------------------------------------------------------------------------- 1 | ver = '1.1.1'; 16 | $this->db = Typecho_Db::get(); 17 | $this->Options = Typecho_Widget::widget('Widget_Options'); 18 | $this->siteUrl = $this->Options->index; 19 | $this->Sitemap = $this->Options->Plugin('Sitemap'); 20 | $this->stat = Typecho_Widget::widget('Widget_Stat'); 21 | $this->sitePageSize = $this->Sitemap->sitePageSize; 22 | $this->pageSize = $this->Options->pageSize; 23 | $this->ymd = date('Y-m-d', time()); 24 | $this->mid = $this->_ckmid(); 25 | if ($this->Sitemap->siteStatus == 0) { 26 | // 关闭了sitemap 27 | $this->checkData(); 28 | } 29 | } 30 | /** 31 | * sitemap 32 | * 33 | */ 34 | public function siteMap() 35 | { 36 | // 不分级 37 | $this->levelSiteList(); 38 | // if ($this->Sitemap->levelSite == 1) { 39 | // $this->levelSiteList(); 40 | // } else { 41 | // $this->siteListXml(); 42 | // } 43 | } 44 | /** 45 | * 不分级 46 | * 47 | */ 48 | public function levelSiteList() 49 | { 50 | $xmlhtml = " " . $this->siteUrl . " " . $this->ymd . " daily 1.0 "; 51 | // 分类 52 | $xmlhtml = $this->retCate(true); 53 | // 单页 54 | if ($this->Sitemap->pagesChangefreq != 'none') { 55 | $obj = $this->widget('Widget_Contents_Page_List'); 56 | if ($obj->have()) { 57 | while ($obj->next()) { 58 | $xmlhtml .= " " . $obj->permalink . " " . $this->ymd . " " . $this->Sitemap->pagesChangefreq . " " . $this->Sitemap->pagesPriority . " "; 59 | } 60 | } 61 | } 62 | // 标签 63 | $xmlhtml .= $this->retTag(true); 64 | // 文章 65 | $xmlhtml .= $this->retPost(true); 66 | // 搜索结果页 67 | $xmlhtml .= $this->retSearch(true); 68 | // 首页翻页 69 | $xmlhtml .= $this->retHomePage(true); 70 | $this->showXml($xmlhtml); 71 | } 72 | /** 73 | * 分级 74 | * 75 | */ 76 | public function siteListXml() 77 | { 78 | $ymd = gmdate("c"); 79 | // 文章总数 80 | $postCount = $this->stat->publishedPostsNum; 81 | // 标签总数 82 | $tagsCount = $this->db->fetchObject($this->db->select(array('COUNT(mid)' => 'num')) 83 | ->from('table.metas') 84 | ->where('table.metas.type = ?', 'tag'))->num; 85 | $tagsCount = intval($tagsCount); 86 | // 主域名 87 | $xmlhtml = ''; 88 | // 文章 89 | $postSize = ceil($postCount / $this->sitePageSize); 90 | for ($i = 0; $i < $postSize; $i++) { 91 | $xmlhtml .= " " . $this->siteUrl . "/sitemap/sitemap_post_" . ($i + 1) . ".xml " . $ymd . " "; 92 | } 93 | // 标签 94 | $tagsSize = ceil($tagsCount / $this->sitePageSize); 95 | for ($i = 0; $i < $tagsSize; $i++) { 96 | $xmlhtml .= " " . $this->siteUrl . "/sitemap/sitemap_tag_" . ($i + 1) . ".xml " . $ymd . " "; 97 | } 98 | // 搜索结果页 99 | $tagsSize = ceil($tagsCount / $this->sitePageSize); 100 | for ($i = 0; $i < $tagsSize; $i++) { 101 | $xmlhtml .= " " . $this->siteUrl . "/sitemap/sitemap_search_" . ($i + 1) . ".xml " . $ymd . " "; 102 | } 103 | // 独立页面 104 | $xmlhtml .= " " . $this->siteUrl . "/sitemap/sitemap_pages.xml " . $ymd . " "; 105 | // 首页翻页分页 106 | $pageSize = ceil(($postCount / $this->pageSize) / $this->sitePageSize); 107 | for ($i = 0; $i < $pageSize; $i++) { 108 | $xmlhtml .= " " . $this->siteUrl . "/sitemap/sitemap_homepage_" . ($i + 1) . ".xml " . $ymd . " "; 109 | } 110 | // 分类总数 111 | $cateList = $this->db->fetchAll($this->db->select('mid')->from('table.metas') 112 | ->where('table.metas.type = ?', 'category') 113 | ->order('table.metas.mid', Typecho_Db::SORT_DESC)); 114 | for ($i = 0; $i < count($cateList); $i++) { 115 | // 分类分页 116 | $xmlhtml .= " " . $this->siteUrl . "/sitemap/sitemap_catepage_" . $cateList[$i]['mid'] . ".xml " . $ymd . " "; 117 | } 118 | $this->sitemapXml($xmlhtml); 119 | $this->xmlJson([ 120 | '标签总数' => $tagsCount, 121 | '标签页数' => $tagsSize, 122 | '文章总数' => $postCount, 123 | '文章页数' => $postSize, 124 | '首页翻页页数' => $pageSize, 125 | '分页数' => $this->sitePageSize, 126 | '分类总数' => $cateList, 127 | ]); 128 | } 129 | /** 130 | * 定向xml 131 | * 132 | */ 133 | public function siteList() 134 | { 135 | $key = $this->request->key; 136 | if ($key == 'post') { 137 | $this->retPost(); 138 | } else if ($key == 'tag') { 139 | $this->retTag(); 140 | } else if ($key == 'cate') { 141 | $this->retCate(); 142 | } else if ($key == 'homepage') { 143 | $this->retHomePage(); 144 | } else if ($key == 'catepage') { 145 | $this->retCatePage(); 146 | } else if ($key == 'pages') { 147 | $this->retPages(); 148 | } else if ($key == 'search') { 149 | $this->retSearch(); 150 | } else { 151 | $this->checkData(); 152 | } 153 | } 154 | /** 155 | * 分类页 156 | * 157 | */ 158 | public function retCate($ret = null) 159 | { 160 | if ($this->Sitemap->cateChangefreq == 'none') { 161 | return ''; 162 | } 163 | $xmlhtml = ''; 164 | $obj = $this->widget('Widget_Metas_Category_List'); 165 | $html = ''; 166 | if ($obj->have()) { 167 | while ($obj->next()) { 168 | if (!in_array($obj->mid, $this->mid)) { 169 | if ($ret === 'html') { 170 | $html .= '
  • ' . $obj->name . '
  • '; 171 | } else { 172 | $xmlhtml .= " " . $obj->permalink . " " . $this->ymd . " " . $this->Sitemap->cateChangefreq . " " . $this->Sitemap->catePriority . " "; 173 | } 174 | } 175 | } 176 | } 177 | if ($ret === 'html') { 178 | return $html; 179 | } 180 | if ($ret) { 181 | return $xmlhtml; 182 | } 183 | $this->showXml($xmlhtml); 184 | } 185 | 186 | /** 187 | * 单页 188 | * 189 | */ 190 | public function retPages() 191 | { 192 | $xmlhtml = ''; 193 | $pages = $this->widget('Widget_Contents_Page_List'); 194 | $data = []; 195 | if ($pages->have()) { 196 | while ($pages->next()) { 197 | $data[] = $pages->permalink; 198 | } 199 | } 200 | // 效验 201 | $this->checkData($data); 202 | for ($i = 0; $i < count($data); $i++) { 203 | $xmlhtml .= " " . $data[$i] . " " . $this->ymd . " " . $this->Sitemap->pagesChangefreq . " " . $this->Sitemap->pagesPriority . " "; 204 | } 205 | $this->showXml($xmlhtml); 206 | } 207 | /** 208 | * 指定分类下的页数 209 | * 210 | */ 211 | public function retCatePage() 212 | { 213 | $page = $this->request->page; 214 | $xmlhtml = ''; 215 | $count = $this->db->fetchObject($this->db->select(array('COUNT(mid)' => 'num')) 216 | ->from('table.relationships') 217 | ->where('table.relationships.mid = ?', $page))->num; 218 | $count = intval($count); 219 | // 效验 220 | $this->checkData($count); 221 | $data = []; 222 | $obj = $this->widget('Widget_Metas_Category_List'); 223 | if ($obj->have()) { 224 | while ($obj->next()) { 225 | if ($obj->mid == $page) { 226 | $data = [ 227 | 'mid' => $obj->mid, 228 | 'permalink' => $obj->permalink, 229 | 'slug' => $obj->slug, 230 | ]; 231 | } 232 | } 233 | } 234 | $xmlhtml = " " . $data['permalink'] . " " . $this->ymd . " " . $this->Sitemap->cateChangefreq . " " . $this->Sitemap->catePriority . " "; 235 | // 分页 236 | $count = ceil($count / $this->pageSize); 237 | for ($i = 1; $i < $count; $i++) { 238 | $xmlhtml .= " " . $data['permalink'] . $i . "/ " . $this->ymd . " " . $this->Sitemap->CatePageChangefreq . " " . $this->Sitemap->CatePagePriority . " "; 239 | } 240 | $this->showXml($xmlhtml); 241 | } 242 | /** 243 | * 首页分页 244 | * 245 | */ 246 | public function retHomePage($ret = null) 247 | { 248 | if ($this->Sitemap->HomePageChangefreq == 'none') { 249 | return ''; 250 | } 251 | $postCount = $this->stat->publishedPostsNum; 252 | $limit = $this->pageSize; 253 | $pages = ceil($postCount / $limit); 254 | $xmlhtml = ''; 255 | $priority = $this->Sitemap->HomePagePriority; 256 | for ($i = 1; $i < $pages; $i++) { 257 | $xmlhtml .= " " . $this->siteUrl . "/" . "page/" . $i . "/ " . $this->ymd . " " . $this->Sitemap->HomePageChangefreq . " " . $priority . " "; 258 | } 259 | if ($ret) { 260 | return $xmlhtml; 261 | } 262 | $this->showXml($xmlhtml); 263 | } 264 | /** 265 | * tag 266 | * 267 | */ 268 | public function retTag($ret = null) 269 | { 270 | if ($this->Sitemap->tagChangefreq == 'none') { 271 | return ''; 272 | } 273 | $page = $this->request->page; 274 | $xmlhtml = ''; 275 | $limit = $this->sitePageSize; 276 | if ($ret) { 277 | $page = 0; 278 | $limit = 10000; 279 | } 280 | $tags = $this->db->fetchAll($this->db->select('slug,mid')->from('table.metas') 281 | ->where('table.metas.type = ?', 'tag') 282 | ->page($page, $limit) 283 | ->order('table.metas.mid', Typecho_Db::SORT_ASC)); 284 | // 效验 285 | if (!$ret) { 286 | $this->checkData($tags); 287 | } 288 | $type = 'tag'; 289 | $routeExists = (NULL != Typecho_Router::get($type)); 290 | for ($i = 1; $i < count($tags); $i++) { 291 | $tags[$i]['slug'] = urlencode($tags[$i]['slug']); 292 | $pathinfo = $routeExists ? Typecho_Router::url($type, $tags[$i]) : '#'; 293 | $permalink = Typecho_Common::url($pathinfo, $this->Options->index); 294 | $xmlhtml .= " " . $permalink . " " . $this->ymd . " " . $this->Sitemap->tagChangefreq . " " . $this->Sitemap->tagPriority . " "; 295 | } 296 | if ($ret) { 297 | return $xmlhtml; 298 | } 299 | $this->showXml($xmlhtml); 300 | } 301 | /** 302 | * 搜索结果页 303 | * 304 | */ 305 | public function retSearch($ret = null) 306 | { 307 | if ($this->Sitemap->searchChangefreq == 'none') { 308 | return ''; 309 | } 310 | $page = $this->request->page; 311 | $xmlhtml = ''; 312 | $limit = $this->sitePageSize; 313 | if ($ret) { 314 | $page = 0; 315 | $limit = 10000; 316 | } 317 | $tags = $this->db->fetchAll($this->db->select('slug,mid')->from('table.metas') 318 | ->where('table.metas.type = ?', 'tag') 319 | ->page($page, $limit) 320 | ->order('table.metas.mid', Typecho_Db::SORT_ASC)); 321 | // 效验 322 | if (!$ret) { 323 | $this->checkData($tags); 324 | } 325 | $type = 'search'; 326 | $routeExists = (NULL != Typecho_Router::get($type)); 327 | for ($i = 1; $i < count($tags); $i++) { 328 | $tags[$i]['keywords'] = urlencode($tags[$i]['slug']); 329 | $pathinfo = $routeExists ? Typecho_Router::url($type, $tags[$i]) : '#'; 330 | $permalink = Typecho_Common::url($pathinfo, $this->Options->index); 331 | $xmlhtml .= " " . $permalink . " " . $this->ymd . " " . $this->Sitemap->searchChangefreq . " " . $this->Sitemap->searchPriority . " "; 332 | } 333 | if ($ret) { 334 | return $xmlhtml; 335 | } 336 | $this->showXml($xmlhtml); 337 | } 338 | /** 339 | * 文章 340 | */ 341 | public function retPost($ret = null) 342 | { 343 | if ($this->Sitemap->postChangefreq == 'none') { 344 | return ''; 345 | } 346 | $xmlhtml = ''; 347 | $reshtml = ''; 348 | $content = Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=' . $this->Sitemap->sitePageSize); 349 | $priority = $this->Sitemap->postPriority; 350 | if ($ret === 'html') { 351 | while ($content->next()) { 352 | // 过滤隐藏分类 353 | if (intval($this->mid[0]) != intval($content->categories[0]['mid'])) { 354 | $reshtml .= '
  • ' . $content->title . '
  • '; 355 | } 356 | } 357 | return $reshtml; 358 | } 359 | while ($content->next()) { 360 | // 过滤隐藏分类 361 | if (intval($this->mid[0]) != intval($content->categories[0]['mid'])) { 362 | $xmlhtml .= " " . $content->permalink . " " . date('Y-m-d', $content->created) . " " . $this->Sitemap->postChangefreq . " " . $priority . " "; 363 | } 364 | } 365 | if ($ret) { 366 | return $xmlhtml; 367 | } 368 | $this->showXml($xmlhtml); 369 | } 370 | 371 | /** 372 | * api网关方法 373 | * 374 | */ 375 | public function siteName() 376 | { 377 | $key = $this->request->key; 378 | if ($key == 'apipost') { 379 | $this->postOneUrl(); 380 | } else if ($key == 'ver') { 381 | $this->postVer(); 382 | } else { 383 | $this->checkData(); 384 | } 385 | } 386 | /** 387 | * ver 388 | * 389 | */ 390 | public function postVer() 391 | { 392 | echo 'v' . $this->ver; 393 | } 394 | 395 | /** 396 | * 通过api推送一个文章url 397 | * 398 | */ 399 | public function postOneUrl() 400 | { 401 | $key = $_GET['key']; 402 | if (!$key) { 403 | $this->xmlJson(null, 'key不能为空', 1001); 404 | } 405 | if ($key !== $this->Sitemap->apiPostToken) { 406 | $this->xmlJson(null, 'key不正确', 1001); 407 | } 408 | $url = $_GET['url']; 409 | if (!$url) { 410 | $this->xmlJson(null, 'url不能为空', 1001); 411 | } 412 | //方法一 413 | $preg = "/http[s]?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/is"; 414 | if (!preg_match($preg, $url)) { 415 | $this->xmlJson(null, 'url不合法', 1001); 416 | } 417 | $res = $this->sendBaiduPost($url); 418 | $this->xmlJson($res['data'], $res['msg'], $res['code']); 419 | } 420 | 421 | public function action() 422 | { 423 | $this->widget('Widget_User')->pass('administrator'); 424 | } 425 | /** 426 | * sitemap html 427 | * 428 | */ 429 | public function sitemaphtml() 430 | { 431 | $posthtml = $this->retPost('html'); 432 | $pages = ceil($this->stat->publishedPostsNum / $this->pageSize); 433 | $homepage = ''; 434 | for ($i = 1; $i <= $pages; $i++) { 435 | $homepage .= '
  • 第' . $i . '页 . ' . $this->Options->title . '
  • '; 436 | } 437 | $cate = $this->retCate('html'); 438 | include 'Sitemap.php'; 439 | } 440 | 441 | /** 442 | * sitemap loc 443 | * 444 | */ 445 | public function sitemapXml($xmlhtml) 446 | { 447 | header("Content-type: text/xml"); 448 | echo ''; 449 | echo ''; 451 | echo $xmlhtml; 452 | echo ''; 453 | exit(); 454 | } 455 | /** 456 | * url loc 457 | * 458 | */ 459 | public function showXml($xmlhtml) 460 | { 461 | header("Content-type: text/xml"); 462 | echo ''; 463 | echo ''; 465 | echo $xmlhtml; 466 | echo ''; 467 | exit(); 468 | } 469 | public function xmlJson($data = null, $msg = '获取成功', $code = 1000) 470 | { 471 | header('Content-Type:application/json; charset=utf-8'); 472 | $ret = [ 473 | 'code' => $code, 474 | 'msg' => $msg, 475 | 'data' => $data, 476 | ]; 477 | exit(json_encode($ret, JSON_UNESCAPED_UNICODE)); 478 | } 479 | /** 480 | * send 481 | * 482 | */ 483 | public function sendBaiduPost($url) 484 | { 485 | $code = 1001; 486 | if (empty($this->Sitemap->apiUrl)) { 487 | $postMsg = '百度推送【失败】,请先设置插件中的接口地址;'; 488 | } else { 489 | $client = Typecho_Http_Client::get(); 490 | $postMsg = '百度推送【失败】,'; 491 | $url = array($url); 492 | if ($client) { 493 | $client->setData(implode(PHP_EOL, $url)) 494 | ->setHeader('Content-Type', 'text/plain') 495 | ->setTimeout(30) 496 | ->send($this->Sitemap->apiUrl); 497 | $status = $client->getResponseStatus(); 498 | $res = $client->getResponseBody(); 499 | $res = json_decode($res, true); 500 | } else { 501 | $status = 200; 502 | try { 503 | $res = $this->curlPost($url); 504 | } catch (\Throwable $th) { 505 | $res = []; 506 | } 507 | } 508 | if (empty($res)) { 509 | $postMsg = '百度推送【失败】,您的服务器不支持curl请求.或没有开启 allow_url_fopen 功能'; 510 | } else { 511 | if ($status == 200 && $res['success'] == 1) { 512 | $code = 1000; 513 | $postMsg = '百度推送【成功】,今日剩余次数' . $res['remain']; 514 | } 515 | if (!empty($res['not_same_site'])) { 516 | $postMsg .= '失败原因:不是本站url,推送的url和token所属的不一致,'; 517 | } 518 | if (!empty($res['message'])) { 519 | $postMsg .= '失败原因:' . $res['message'] . ';请检查token是否正确;'; 520 | } 521 | } 522 | } 523 | return [ 524 | 'code' => $code, 525 | 'data' => $res, 526 | 'msg' => $postMsg 527 | ]; 528 | } 529 | public function curlPost($url = null, $code = false) 530 | { 531 | $ch = curl_init(); 532 | $options = array( 533 | CURLOPT_URL => $this->Sitemap->apiUrl, 534 | CURLOPT_POST => true, 535 | CURLOPT_RETURNTRANSFER => true, 536 | CURLOPT_POSTFIELDS => implode("\n", $url), 537 | CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), 538 | ); 539 | curl_setopt_array($ch, $options); 540 | $result = curl_exec($ch); 541 | $result = json_decode($result, true); 542 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 543 | if ($code === true) { 544 | return array( 545 | 'code' => $httpCode, 546 | 'data' => $result 547 | ); 548 | } 549 | return $result; 550 | } 551 | /*检测数据*/ 552 | private function checkData($data = null) 553 | { 554 | if (!$data) { 555 | throw new Typecho_Widget_Exception(_t('页面不存在'), 404); 556 | } 557 | return true; 558 | } 559 | // 转换mid为数组 560 | public function _ckmid() 561 | { 562 | $mid = []; 563 | if ($this->Sitemap->mid) { 564 | $mid = explode(',', $this->Sitemap->mid); 565 | if (!is_array($mid)) { 566 | $mid = []; 567 | } 568 | } 569 | return $mid; 570 | } 571 | // 隐藏指定分类下的所有文章 572 | private function _setMiddata($content, $mid) 573 | { 574 | $mids = $this->db->fetchAll($this->db->select('cid,mid')->from('table.relationships') 575 | ->where('table.relationships.mid in ? ', $mid)); 576 | $mid = []; 577 | foreach ($mids as $val) { 578 | $mid[$val['cid']] = $val['cid']; 579 | } 580 | $data = []; 581 | foreach ($content as $v) { 582 | if (empty($mid[$v['cid']])) { 583 | $data[] = $v; 584 | } 585 | } 586 | $content = null; 587 | return $data; 588 | } 589 | } 590 | --------------------------------------------------------------------------------