├── Sitemap ├── XML.php ├── API.php ├── Push.php ├── Plugin.php └── Action.php ├── LICENSE └── README.md /Sitemap/XML.php: -------------------------------------------------------------------------------- 1 | plugin('Sitemap')->sitemap_cachetime; 10 | $cachetime = $cachetime * 86400; 11 | header('Cache-Control:max-age=' . $cachetime); 12 | header("Content-Type: application/xml"); 13 | if (time() - $XmlTime > $cachetime) { 14 | require_once("Action.php"); 15 | update('update', 'auto'); 16 | }; 17 | //返回xml 18 | $myfile = fopen($dir, "r"); 19 | echo fread($myfile, filesize($dir)); 20 | fclose($myfile); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ethanzhao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sitemap-For-Typecho 2 | 3 | 用着好的话麻烦给个star,十分感谢!!! 4 | 5 | ## 功能 6 | 7 | 1、为`Typecho`生成`sitemap`包含**首页、独立页面、分类、标签、文章** 8 | 9 | 2、推送百度搜索资源平台,目前仅支持普通收录推送,卑微的我没快速收录权限 10 | 11 | 3、支持永久链接中的全部参数,包括以下。 12 | 13 | ``` 14 | 可用参数: 15 | {cid} 日志 ID 16 | {slug} 日志缩略名 17 | {category} 分类 18 | {directory} 多级分类 19 | {year} 年 20 | {month} 月 21 | {day} 日 22 | ``` 23 | 24 | ~~不支持发布文章自动更新`sitemap`及自动推送,可能会影响文章发布速度所以没有做支持~~ 25 | 26 | ### API说明 27 | 28 | | 参数 | 值 | 说明 | 29 | | ------- | --------- | ----------------- | 30 | | sitemap | update | 更新sitemap | 31 | | push | main | 推送核心文章 | 32 | | push | all | 推送全部文章 | 33 | | push | new | 推送最新文章 | 34 | | token | API token | 插件中的API token | 35 | 36 | ## 更新 37 | 38 | ### 1.1.0 39 | 40 | 修改推送规则 41 | 42 | ### 1.2.0 43 | 44 | 修改缓存机制,以前是存数据库会导致内容超出长度,现在改为存储缓存文件 45 | 46 | ### 1.2.1 47 | 48 | 修改读取分类的错误 49 | 50 | ### 1.3.0 51 | 52 | 增加api刷新sitemap功能 53 | 54 | 增加api推送文章功能发布文章自动推送当前文章 55 | 56 | 发布文章更新sitemap 57 | 58 | 增加推送日志和Sitemap更新日志存入插件目录下 59 | 60 | 修复文章不满20篇的推送异常报错 61 | 62 | 修改手动推送后显示链接乱的问题 63 | 64 | ### 1.3.1 65 | 66 | 修复非默认后台入口`/admin/`的推送功能无法使用 67 | 68 | ### 1.3.2 69 | 70 | 修复`php8`环境下的的报错 71 | 72 | ### 1.3.3 73 | 74 | 修复错误 永久链接使用按分类归档时Sitemap文章链接错误 75 | 76 | ### 1.3.4 77 | 78 | 修复错误 永久链接使用按分类归档时推送百度的文章链接错误 79 | 80 | ### 1.5 81 | 82 | 更新 支持文章链接中的全部参数 83 | 84 | ### 1.5.1 85 | 86 | 更新 支持分类永久链接的`{directory}`参数 87 | 88 | ### 1.6 89 | 90 | 修复 各类自定义文章链接自动推送百度出现的链接错误(建议所有用户更新到此版本) 91 | 92 | ### 1.7 93 | 94 | 修复 api推送最新文章的异常报错 95 | 新增 api缓存头,避免CDN进行缓存 96 | 97 | ### 1.8 98 | 99 | 修复 百度推送更新接口,更新百度推送的方法。 100 | 增加 自定义设置推送最新文章数量 101 | 102 | *卸禁用后删除插件,再更新!插件目录设置777权限* 103 | 104 | 博客:[https://www.zhaoyingtian.com/archives/93.html](https://www.zhaoyingtian.com/archives/93.html) 105 | -------------------------------------------------------------------------------- /Sitemap/API.php: -------------------------------------------------------------------------------- 1 | plugin('Sitemap')->api_token == null) { 12 | echo 'api closed'; 13 | exit; 14 | } 15 | if (isset($_GET['token']) && $_GET['token'] === Helper::options()->plugin('Sitemap')->api_token) { 16 | require_once("Action.php"); 17 | $array = array(); 18 | if (isset($_GET['sitemap']) && $_GET['sitemap'] === 'update') { 19 | //add arr 20 | $arr = array( 21 | 'update' => update('update', 'api'), 22 | ); 23 | $array = array_merge($array, $arr); 24 | } 25 | if (isset($_GET['push']) && $_GET['push'] === 'main') { 26 | //add arr 27 | $arr = array( 28 | 'push' => submit('typecho', 'api'), 29 | ); 30 | $array = array_merge($array, $arr); 31 | } 32 | if (isset($_GET['push']) && $_GET['push'] === 'all') { 33 | //add arr 34 | $arr = array( 35 | 'push' => submit('archive_all', 'api'), 36 | ); 37 | $array = array_merge($array, $arr); 38 | } 39 | if (isset($_GET['push']) && $_GET['push'] === 'new') { 40 | //add arr 41 | $arr = array( 42 | 'push' => submit('archive', 'api'), 43 | ); 44 | $array = array_merge($array, $arr); 45 | } 46 | echo json_encode($array); 47 | } else { 48 | //返回错误 49 | echo 'token error'; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sitemap/Push.php: -------------------------------------------------------------------------------- 1 | adminUrl)); 9 | } 10 | 11 | ?> 12 | 13 | 14 | 21 | 22 |
23 |
24 |
25 |

百度搜索资源平台

26 |
27 |

常规更新推送

28 | 29 |

更新网站sitemap文件

30 | 31 | 32 |

推送最新plugin('Sitemap')->NumberOfLatestArticles; ?>篇文章

33 |
34 |

暴力推送

35 |

不建议经常使用

36 | 37 |

首页、分类、独立页面

38 | 39 |

所有文章的URL

40 | 41 | 稍后自动返回页面

'; 45 | echo '

' . submit('typecho', 'web') . '

'; 46 | header("Refresh:10;url=" . Typecho_Common::url('/extending.php?panel=Sitemap%2FPush.php', Helper::options()->adminUrl)); 47 | } 48 | if (isset($_GET['action']) && $_GET['action'] === 'baidu_archive_all') { 49 | require_once("Action.php"); 50 | echo '

稍后自动返回页面

'; 51 | echo '

' . submit('archive_all', 'web') . '

'; 52 | header("Refresh:10;url=" . Typecho_Common::url('/extending.php?panel=Sitemap%2FPush.php', Helper::options()->adminUrl)); 53 | } 54 | if (isset($_GET['action']) && $_GET['action'] === 'baidu_archive') { 55 | require_once("Action.php"); 56 | echo '

稍后自动返回页面

'; 57 | echo '

' . submit('archive', 'web') . '

'; 58 | header("Refresh:10;url=" . Typecho_Common::url('/extending.php?panel=Sitemap%2FPush.php', Helper::options()->adminUrl)); 59 | } 60 | ?> 61 |
62 |
63 |
64 | -------------------------------------------------------------------------------- /Sitemap/Plugin.php: -------------------------------------------------------------------------------- 1 | finishPublish = array('Sitemap_Plugin', 'auto'); 28 | Typecho_Plugin::factory('Widget_Contents_Page_Edit')->finishPublish = array('Sitemap_Plugin', 'auto'); 29 | } 30 | 31 | /** 32 | * 禁用插件方法,如果禁用失败,直接抛出异常 33 | * 34 | * @static 35 | * @access public 36 | * @return void 37 | * @throws Typecho_Plugin_Exception 38 | */ 39 | public static function deactivate() 40 | { 41 | Helper::removeRoute('sitemap-api'); 42 | Helper::removeRoute('sitemap'); 43 | Helper::removePanel(1, 'Sitemap/Push.php'); 44 | $dir = __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/Sitemap/sitemap'; 45 | unlink($dir); 46 | } 47 | 48 | /** 49 | * 获取插件配置面板 50 | * 51 | * @access public 52 | * @param Typecho_Widget_Helper_Form $form 配置面板 53 | * @return void 54 | */ 55 | public static function config(Typecho_Widget_Helper_Form $form) 56 | { 57 | if (isset($_GET['action']) && $_GET['action'] === 'update_sitemap') { 58 | self::update_sitemap(); 59 | } 60 | $sitemap_cachetime = new Typecho_Widget_Helper_Form_Element_Text('sitemap_cachetime', NULL, '7', _t('Sitemap 缓存时间'), '单位(天)'); 61 | $form->addInput($sitemap_cachetime); 62 | $baidu_url = new Typecho_Widget_Helper_Form_Element_Text('baidu_url', NULL, NULL, _t('百度推送接口 URL'), '请在百度搜索资源平台查看,目前仅支持普通收录'); 63 | $form->addInput($baidu_url); 64 | 65 | try { 66 | if (Helper::options()->plugin('Sitemap')->api_token == null) { 67 | $randString = Typecho_Common::randString(32); 68 | } else { 69 | $randString = Helper::options()->plugin('Sitemap')->api_token; 70 | } 71 | } catch (Exception $e) { 72 | $randString = Typecho_Common::randString(32); 73 | } 74 | $web_token = new Typecho_Widget_Helper_Form_Element_Text('api_token', NULL, $randString, _t('API token'), '自动生成无需修改,留空则不开启API功能
' . Helper::options()->index . '/sitemap-api?sitemap=update&push=new&token=' . $randString); 75 | $form->addInput($web_token); 76 | $NumberOfLatestArticles = new Typecho_Widget_Helper_Form_Element_Text('NumberOfLatestArticles', NULL, '5', _t('推送最新文章数量'), '单位(篇)'); 77 | $form->addInput($NumberOfLatestArticles); 78 | $AutoPush = new Typecho_Widget_Helper_Form_Element_Radio('AutoPush', array(0 => _t('不开启'), 1 => _t('开启')), 0, _t('自动推送文章'), '发布文章自动推送当前文章'); 79 | $form->addInput($AutoPush); 80 | $AutoSitemap = new Typecho_Widget_Helper_Form_Element_Radio('AutoSitemap', array(0 => _t('不开启'), 1 => _t('开启')), 0, _t('自动更新Sitemap'), '发布文章更新Sitemap,可能降低文章发布速度'); 81 | $form->addInput($AutoSitemap); 82 | $PluginLog = new Typecho_Widget_Helper_Form_Element_Radio('PluginLog', array(0 => _t('不开启'), 1 => _t('开启')), 0, _t('插件日志'), '将推送日志和Sitemap更新日志存入插件目录下'); 83 | $form->addInput($PluginLog); 84 | $Btn = new Typecho_Widget_Helper_Form_Element_Submit(); 85 | $Btn->value(_t('更新 sitemap.xml')); 86 | $Btn->description(_t('用于手动更新sitemap.xml')); 87 | $Btn->input->setAttribute('class', 'btn primary'); 88 | $Btn->input->setAttribute('formaction', Typecho_Common::url('/options-plugin.php?config=Sitemap&action=update_sitemap', Helper::options()->adminUrl)); 89 | $form->addItem($Btn); 90 | } 91 | /** 92 | * 更新 sitemap 93 | */ 94 | public static function update_sitemap() 95 | { 96 | require_once("Action.php"); //引入 97 | update('update', 'web'); //更新xml 98 | header("location:" . Typecho_Common::url('/options-plugin.php?config=Sitemap', Helper::options()->adminUrl)); 99 | } 100 | /** 101 | * 插件实现方法 102 | * 103 | * @access public 104 | * @return void 105 | */ 106 | public static function render() 107 | { 108 | } 109 | 110 | /** 111 | * 个人用户的配置面板 112 | * 113 | * @access public 114 | * @param Typecho_Widget_Helper_Form $form 115 | * @return void 116 | */ 117 | public static function personalConfig(Typecho_Widget_Helper_Form $form) 118 | { 119 | } 120 | 121 | /** 122 | * 自动推送 123 | * @param $contents 文章内容 124 | * @param $class 调用接口的类 125 | * @throws Typecho_Plugin_Exception 126 | */ 127 | public static function auto($contents, $class) 128 | { 129 | //如果文章属性为隐藏或滞后发布 130 | if ('publish' != $contents['visibility'] || $contents['created'] > time()) { 131 | return; 132 | } 133 | //通过创建时间查找cid 134 | $db = Typecho_Db::get(); 135 | $cid = $db->fetchRow($db->select('cid')->from('table.contents')->where('created = ?', $contents['created'])); 136 | //引用action.php调用getPermalink 137 | require_once("Action.php"); 138 | //获取文章链接 139 | $url = getPermalink($cid); 140 | $urls = array( 141 | $url, 142 | ); 143 | //检查自动推送文章开关 144 | if (Helper::options()->plugin('Sitemap')->AutoPush == 1) { 145 | $api = Helper::options()->plugin('Sitemap')->baidu_url; 146 | $ch = curl_init(); 147 | $options = array( 148 | CURLOPT_URL => $api, 149 | CURLOPT_POST => true, 150 | CURLOPT_RETURNTRANSFER => true, 151 | CURLOPT_POSTFIELDS => implode("\n", $urls), 152 | CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), 153 | ); 154 | curl_setopt_array($ch, $options); 155 | $result_json = curl_exec($ch); 156 | $result = json_decode($result_json, true); 157 | //获取时间 158 | $time = date('Y-m-d H:i:s', time()); 159 | //写入日志 160 | $log = '【' . $time . '】' . 'auto' . '成功推送' . $result['success'] . '条,今日剩余可推送' . $result['remain'] . '条' . "\n" . $url . "\n"; 161 | if (Helper::options()->plugin('Sitemap')->baidu_url == null) { 162 | $log = '【' . $time . '】' . 'auto' . '推送失败,未填写百度推送接口 URL'; 163 | } else { 164 | $api = Helper::options()->plugin('Sitemap')->baidu_url; 165 | } 166 | if (Helper::options()->plugin('Sitemap')->PluginLog == 1) { 167 | file_put_contents(__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/Sitemap/log.txt', $log, FILE_APPEND); 168 | } 169 | } 170 | 171 | //检查自动更新Sitemap开关 172 | if (Helper::options()->plugin('Sitemap')->AutoSitemap == 1) { 173 | //获取时间 174 | $time = date('Y-m-d H:i:s', time()); 175 | //更新sitemap 176 | require_once("Action.php"); 177 | update('update', 'auto'); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /Sitemap/Action.php: -------------------------------------------------------------------------------- 1 | 8 | ' . "\n"; 11 | $footer = ''; 12 | //首页 13 | $index = Helper::options()->siteUrl; 14 | $index_result = $index_result . "\t\n"; 15 | $index_result = $index_result . "\t\t" . $index . "\n"; 16 | $index_result = $index_result . "\t\talways\n"; 17 | $index_result = $index_result . "\t\t1\n"; 18 | $index_result = $index_result . "\t\n"; 19 | //独立页面 20 | $pages = $db->fetchAll($db->select()->from('table.contents') 21 | ->where('table.contents.status = ?', 'publish') 22 | ->where('table.contents.created < ?', $options->gmtTime) 23 | ->where('table.contents.type = ?', 'page') 24 | ->order('table.contents.created', Typecho_Db::SORT_DESC)); 25 | foreach ($pages as $page) { 26 | $type = $page['type']; 27 | $routeExists = (NULL != Typecho_Router::get($type)); 28 | $page['pathinfo'] = $routeExists ? Typecho_Router::url($type, $page) : '#'; 29 | $page['permalink'] = Typecho_Common::url($page['pathinfo'], $options->index); 30 | $page_result = $page_result . "\t\n"; 31 | $page_result = $page_result . "\t\t" . $page['permalink'] . "\n"; 32 | $page_result = $page_result . "\t\t" . date('Y-m-d', $page['modified']) . "\n"; 33 | $page_result = $page_result . "\t\talways\n"; 34 | $page_result = $page_result . "\t\t0.8\n"; 35 | $page_result = $page_result . "\t\n"; 36 | } 37 | //分类 38 | $categorys = $db->fetchAll($db->select()->from('table.metas') 39 | ->where('table.metas.type = ?', 'category')); 40 | foreach ($categorys as $category) { 41 | $category_result = $category_result . "\t\n"; 42 | $category_result = $category_result . "\t\t" . getPermalinkCategory($category) . "\n"; 43 | $category_result = $category_result . "\t\talways\n"; 44 | $category_result = $category_result . "\t\t0.5\n"; 45 | $category_result = $category_result . "\t\n"; 46 | } 47 | //文章 48 | $archives = $db->fetchAll($db->select()->from('table.contents') 49 | ->where('table.contents.status = ?', 'publish') 50 | ->where('table.contents.created < ?', $options->gmtTime) 51 | ->where('table.contents.type = ?', 'post') 52 | ->order('table.contents.created', Typecho_Db::SORT_DESC)); 53 | foreach ($archives as $archive) { 54 | $archive_result = $archive_result . "\t\n"; 55 | $archive_result = $archive_result . "\t\t" . getPermalink($archive['cid']) . "\n"; 56 | $archive_result = $archive_result . "\t\t" . date('Y-m-d', $archive['modified']) . "\n"; 57 | $archive_result = $archive_result . "\t\talways\n"; 58 | $archive_result = $archive_result . "\t\t0.8\n"; 59 | $archive_result = $archive_result . "\t\n"; 60 | } 61 | //tag 62 | $tags = $db->fetchAll($db->select()->from('table.metas') 63 | ->where('table.metas.type = ?', 'tag')); 64 | foreach ($tags as $tag) { 65 | $type = $tag['type']; 66 | $routeExists = (NULL != Typecho_Router::get($type)); 67 | $tag['pathinfo'] = $routeExists ? Typecho_Router::url($type, $tag) : '#'; 68 | $tag['permalink'] = Typecho_Common::url($tag['pathinfo'], $options->index); 69 | $tag_result = $tag_result . "\t\n"; 70 | $tag_result = $tag_result . "\t\t" . $tag['permalink'] . "\n"; 71 | $tag_result = $tag_result . "\t\talways\n"; 72 | $tag_result = $tag_result . "\t\t0.5\n"; 73 | $tag_result = $tag_result . "\t\n"; 74 | } 75 | $result = $header . $index_result . $page_result . $category_result . $archive_result . $tag_result . $footer; //xml内容 76 | $dir = __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/Sitemap/sitemap'; 77 | if ($function === 'activate') { //激活 78 | $myfile = fopen($dir, "w"); 79 | fwrite($myfile, $result); 80 | fclose($myfile); 81 | } 82 | if ($function === 'update') { //更新 83 | unlink($dir); 84 | $myfile = fopen($dir, "w"); 85 | fwrite($myfile, $result); 86 | fclose($myfile); 87 | //获取时间 88 | $time = date('Y-m-d H:i:s', time()); 89 | //写入日志 90 | $log = '【' . $time . '】' . $web . '成功更新sitemap.xml' . "\n"; 91 | if (Helper::options()->plugin('Sitemap')->PluginLog == 1) { 92 | file_put_contents(__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/Sitemap/log.txt', $log, FILE_APPEND); 93 | } 94 | //返回提示 95 | if ($web === 'web') { 96 | Typecho_Widget::widget('Widget_Notice')->set(_t("更新 sitemap.xml 成功"), 'success'); 97 | } 98 | if ($web === 'api') { 99 | return "success"; 100 | } 101 | } 102 | } 103 | function submit($function, $web) //推送百度 104 | { 105 | $NumberOfLatestArticles = (int)Helper::options()->plugin('Sitemap')->NumberOfLatestArticles; 106 | //检查baidu_url 107 | if (Helper::options()->plugin('Sitemap')->baidu_url == NULL) { 108 | if ($web === 'web') { 109 | Typecho_Widget::widget('Widget_Notice')->set(_t("请先设置百度站长平台的站点地址"), 'error'); 110 | return; 111 | } 112 | if ($web === 'api') { 113 | return "BadiuApi is null"; 114 | } 115 | } 116 | $db = Typecho_Db::get(); 117 | $options = Typecho_Widget::widget('Widget_Options'); 118 | if ($function === 'typecho') { 119 | //首页 120 | $index = Helper::options()->siteUrl; 121 | $urls = array($index); 122 | //独立页面 123 | $pages = $db->fetchAll($db->select()->from('table.contents') 124 | ->where('table.contents.status = ?', 'publish') 125 | ->where('table.contents.created < ?', $options->gmtTime) 126 | ->where('table.contents.type = ?', 'page') 127 | ->order('table.contents.created', Typecho_Db::SORT_DESC)); 128 | foreach ($pages as $page) { 129 | $type = $page['type']; 130 | $routeExists = (NULL != Typecho_Router::get($type)); 131 | $page['pathinfo'] = $routeExists ? Typecho_Router::url($type, $page) : '#'; 132 | $page['permalink'] = Typecho_Common::url($page['pathinfo'], $options->index); 133 | array_push($urls, $page['permalink']); 134 | } 135 | //分类 136 | $categorys = $db->fetchAll($db->select()->from('table.metas') 137 | ->where('table.metas.type = ?', 'category')); 138 | foreach ($categorys as $category) { 139 | array_push($urls, getPermalinkCategory($category)); 140 | } 141 | echo count($urls); 142 | } 143 | if ($function === 'archive' || $function === 'archive_all') { 144 | $urls = array(); 145 | //文章 146 | $archives = $db->fetchAll($db->select()->from('table.contents') 147 | ->where('table.contents.status = ?', 'publish') 148 | ->where('table.contents.created < ?', $options->gmtTime) 149 | ->where('table.contents.type = ?', 'post') 150 | ->order('table.contents.created', Typecho_Db::SORT_DESC)); 151 | if ($function === 'archive') { 152 | //获取文章数量 153 | $postnum = count($archives); 154 | //如果文章数量大于$NumberOfLatestArticles,只推送最新的$NumberOfLatestArticles篇 155 | if ($postnum >= $NumberOfLatestArticles) { 156 | for ($x = 0; $x < $NumberOfLatestArticles; $x++) { 157 | $archive = $archives[$x]; 158 | array_push($urls, getPermalink($archive['cid'])); 159 | } 160 | } else { 161 | if ($web === 'web') { 162 | Typecho_Widget::widget('Widget_Notice')->set(_t("文章小于" . $NumberOfLatestArticles . "篇"), 'error'); 163 | return; 164 | } 165 | if ($web === 'api') { 166 | return "Number of articles less than " . $NumberOfLatestArticles; 167 | } 168 | } 169 | } 170 | 171 | if ($function === 'archive_all') { 172 | foreach ($archives as $archive) { 173 | array_push($urls, getPermalink($archive['cid'])); 174 | } 175 | } 176 | } 177 | 178 | $api = Helper::options()->plugin('Sitemap')->baidu_url; 179 | $ch = curl_init(); 180 | $options = array( 181 | CURLOPT_URL => $api, 182 | CURLOPT_POST => true, 183 | CURLOPT_RETURNTRANSFER => true, 184 | CURLOPT_POSTFIELDS => implode("\n", $urls), 185 | CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), 186 | ); 187 | curl_setopt_array($ch, $options); 188 | $result_json = curl_exec($ch); 189 | $result = json_decode($result_json, true); 190 | //获取时间 191 | $time = date('Y-m-d H:i:s', time()); 192 | //推送状态判断{"error":400,"message":"over quota"} 193 | if ($result['error'] == 400) { 194 | if ($result['message'] == "over quota") { 195 | $message = '超过推送限额'; 196 | } 197 | if ($result['message'] == "empty content") { 198 | $message = '推送网站列表为空'; 199 | } 200 | //写入日志 201 | $log = '【' . $time . '】' . $web . '推送失败:' . $message . "\n"; 202 | if (Helper::options()->plugin('Sitemap')->PluginLog == 1) { 203 | file_put_contents(__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/Sitemap/log.txt', $log, FILE_APPEND); 204 | } 205 | //返回提示 206 | if ($web === 'web') { 207 | Typecho_Widget::widget('Widget_Notice')->set(_t("推送失败"), 'error'); 208 | return '推送失败:' . $message; 209 | } 210 | if ($web === 'api') { 211 | return $result_json; 212 | } 213 | } else { 214 | //写入日志 215 | $log = '【' . $time . '】' . $web . '成功推送:' . $result['success'] . '条,今日剩余可推送' . $result['remain'] . '条' . $url_list . "\n"; 216 | if (Helper::options()->plugin('Sitemap')->PluginLog == 1) { 217 | file_put_contents(__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/Sitemap/log.txt', $log, FILE_APPEND); 218 | } 219 | //返回提示 220 | if ($web === 'web') { 221 | Typecho_Widget::widget('Widget_Notice')->set(_t("成功推送"), 'success'); 222 | return '成功推送:' . $result['success'] . '条,今日剩余可推送' . $result['remain'] . '条'; 223 | } 224 | if ($web === 'api') { 225 | return $result_json; 226 | } 227 | } 228 | } 229 | //生成文章永久链接 230 | function getPermalink($cid) 231 | { 232 | $db = Typecho_Db::get(); 233 | // 获取文章的创建时间和slug 234 | $row = $db->fetchRow($db->select('table.contents.created', 'table.contents.slug', 'table.contents.type', 'table.contents.cid') 235 | ->from('table.contents') 236 | ->where('table.contents.type = ?', 'post') 237 | ->where('table.contents.cid = ?', $cid) 238 | ->limit(1)); 239 | $slug = $row['slug']; 240 | // 获取文章的创建时间 241 | $created = $row['created']; 242 | $year = date('Y', $created); 243 | $month = date('m', $created); 244 | $day = date('d', $created); 245 | // 获取分类 246 | $category = $db->fetchRow($db->select('table.metas.slug') 247 | ->from('table.relationships') 248 | ->join('table.metas', 'table.metas.mid = table.relationships.mid') 249 | ->where('table.relationships.cid = ?', $cid) 250 | ->where('table.metas.type = ?', 'category') 251 | ->limit(1)); 252 | $category = $category['slug']; 253 | // 获取目录分类 254 | $directory = ''; 255 | $parent = $db->fetchRow($db->select('table.metas.parent') 256 | ->from('table.metas') 257 | ->where('table.metas.type = ?', 'category') 258 | ->where('table.metas.slug = ?', $category) 259 | ->limit(1)); 260 | while ($parent['parent'] != 0) { 261 | $parent = $db->fetchRow($db->select('table.metas.slug', 'table.metas.parent') 262 | ->from('table.metas') 263 | ->where('table.metas.type = ?', 'category') 264 | ->where('table.metas.mid = ?', $parent['parent']) 265 | ->limit(1)); 266 | $directory = $parent['slug'] . '/' . $directory; 267 | } 268 | $directory = $directory . $category; 269 | // 返回链接 270 | if ($row) { 271 | $options = Typecho_Widget::widget('Widget_Options'); 272 | $permalink = Typecho_Common::url(Typecho_Router::url($row['type'], $row), $options->index); 273 | $permalink = str_replace('{slug}', $slug, $permalink); 274 | $permalink = str_replace('{category}', $category, $permalink); 275 | $permalink = str_replace('{directory}', $directory, $permalink); 276 | $permalink = str_replace('{year}', $year, $permalink); 277 | $permalink = str_replace('{month}', $month, $permalink); 278 | $permalink = str_replace('{day}', $day, $permalink); 279 | return $permalink; 280 | } 281 | } 282 | //生成分类永久链接 283 | function getPermalinkCategory($category) 284 | { 285 | $options = Typecho_Widget::widget('Widget_Options'); 286 | $type = $category['type']; 287 | $routeExists = (NULL != Typecho_Router::get($type)); 288 | $category['pathinfo'] = $routeExists ? Typecho_Router::url($type, $category) : '#'; 289 | $category['permalink'] = Typecho_Common::url($category['pathinfo'], $options->index); 290 | $directory = ''; 291 | // 获取目录分类 292 | $db = Typecho_Db::get(); 293 | $parent = $db->fetchRow($db->select('table.metas.parent') 294 | ->from('table.metas') 295 | ->where('table.metas.type = ?', 'category') 296 | ->where('table.metas.slug = ?', $category['slug']) 297 | ->limit(1)); 298 | while ($parent['parent'] != 0) { 299 | $parent = $db->fetchRow($db->select('table.metas.slug', 'table.metas.parent') 300 | ->from('table.metas') 301 | ->where('table.metas.type = ?', 'category') 302 | ->where('table.metas.mid = ?', $parent['parent']) 303 | ->limit(1)); 304 | $directory = $parent['slug'] . '/' . $directory; 305 | } 306 | $directory = $directory . $category['slug']; 307 | $category['permalink'] = str_replace('{directory}', $directory, $category['permalink']); 308 | return $category['permalink']; 309 | } 310 | --------------------------------------------------------------------------------