├── .gitignore
├── README.md
├── Plugin.php
├── Logs.php
└── Action.php
/.gitignore:
--------------------------------------------------------------------------------
1 | *.mdb
2 | *.ldb
3 | *.sln
4 | *.config
5 | Debug/
6 | Release/
7 | obj/
8 | config.inc.php
9 | .idea/*
10 | *.pyc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BaiduSubmit
2 | A typecho plugin for baidu SEO
3 |
4 | 老高目测对SEO还是有一些用处的。
5 |
6 | ## 功能
7 |
8 | 提交sitemap给百度服务器,优化收录。
9 |
10 | 由于插件会在添加文章、删除文章时向百度post信息,做这些操作的时候可能会比以前慢一点。
11 |
12 | 同时支持主动推送功能,目前每天有50条限额! ----> 对应功能 百度站长--链接提交--自动提交--主动推送
13 |
14 | 新的百度xml地图为地址为 `http://yourweb/baidu_sitemap.xml` ----> 对应功能 百度站长--链接提交--自动提交--sitemap
15 |
16 | 请在百度站长后台设置sitemap,主动推送功能将会在每次编辑完文章后主动推送,或者在百度结构化日志界面批量推送!
17 |
18 | ## 安装
19 |
20 | 将文件夹重命名为`BaiduSubmit`,然后拷贝至`usr/plugins/`下,最后在后台->插件处安装。
21 |
22 | ## 升级方法
23 |
24 | **请先禁用插件后再升级**
25 |
26 | ## 使用
27 |
28 | 全新的日志记录功能!
29 |
30 | ![日志记录][1]
31 |
32 |
33 | [1]: http://www.phpgao.com/usr/uploads/2015/05/879628597.png
--------------------------------------------------------------------------------
/Plugin.php:
--------------------------------------------------------------------------------
1 | finishPublish = array('BaiduSubmit_Action', 'send');
21 | Typecho_Plugin::factory('Widget_Contents_Page_Edit')->finishPublish = array('BaiduSubmit_Action', 'send');
22 |
23 | //添加网站地图功能
24 | Helper::addRoute('baidu_sitemap', '/baidu_sitemap.xml', 'BaiduSubmit_Action', 'sitemap');
25 | Helper::addPanel(1, 'BaiduSubmit/Logs.php', '百度结构化日志', '百度结构化日志', 'administrator');
26 | Helper::addRoute('baidu_sitemap_advanced', __TYPECHO_ADMIN_DIR__ . 'baidu_sitemap/advanced', 'BaiduSubmit_Action', 'send_all');
27 | return $msg . '请进入设置填写接口调用地址';
28 | }
29 |
30 | public static function render(){
31 | $options = Helper::options();
32 | echo '百度结构化插件';
35 | }
36 |
37 | public static function deactivate()
38 | {
39 | $msg = self::uninstall();
40 | return $msg . '插件卸载成功';
41 | }
42 |
43 | public static function index(){
44 | echo 1;
45 | }
46 |
47 | public static function config(Typecho_Widget_Helper_Form $form)
48 | {
49 |
50 | $element = new Typecho_Widget_Helper_Form_Element_Text('api', null, null, _t('接口调用地址'), '请登录百度站长平台获取');
51 | $form->addInput($element);
52 |
53 | $element = new Typecho_Widget_Helper_Form_Element_Text('group', null, 15, _t('分组URL数'), '每天最多只能发送50条,请酌情设置');
54 | $form->addInput($element);
55 |
56 | $element = new Typecho_Widget_Helper_Form_Element_Radio('delete', array(0 => '不删除', 1 => '删除'), 0, _t('卸载是否删除数据表'));
57 | $form->addInput($element);
58 | }
59 |
60 | public static function personalConfig(Typecho_Widget_Helper_Form $form)
61 | {
62 | }
63 |
64 |
65 |
66 | public static function install()
67 | {
68 |
69 | try {
70 | return self::addTable();
71 | } catch (Typecho_Db_Exception $e) {
72 | if ('42S01' == $e->getCode()) {
73 | $msg = '数据库已存在!';
74 | return $msg;
75 | }
76 | }
77 | }
78 |
79 | public static function uninstall()
80 | {
81 | //删除路由
82 | Helper::removeRoute('baidu_sitemap');
83 | Helper::removeRoute('baidu_sitemap_advanced');
84 | Helper::removePanel(1, 'BaiduSubmit/Logs.php');
85 | //获取配置,是否删除数据表
86 | if (Helper::options()->plugin('BaiduSubmit')->delete == 1) {
87 | return self::remove_table();
88 | }
89 | }
90 |
91 | public static function addTable()
92 | {
93 | $db = Typecho_Db::get();
94 | $prefix = $db->getPrefix();
95 | $sql = "CREATE TABLE `{$prefix}baidusubmit` (
96 | `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
97 | `subject` varchar(255) COMMENT '主体',
98 | `action` varchar(255) COMMENT '动作',
99 | `object` varchar(255) COMMENT '对象',
100 | `result` varchar(255) COMMENT '结果',
101 | `more` text COMMENT '更多信息',
102 | `time` bigint COMMENT '时间',
103 | PRIMARY KEY (`id`)
104 | )DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
105 | $db->query($sql);
106 | return "数据库安装成功!";
107 | }
108 |
109 | public static function remove_table()
110 | {
111 | //删除表
112 | $db = Typecho_Db::get();
113 | $prefix = $db->getPrefix();
114 | try {
115 | $db->query("DROP TABLE `" . $prefix . "baidusubmit`", Typecho_Db::WRITE);
116 | } catch (Typecho_Exception $e) {
117 | return "删除日志表失败!";
118 | }
119 | return "删除日志表成功!";
120 | }
121 |
122 |
123 | }
--------------------------------------------------------------------------------
/Logs.php:
--------------------------------------------------------------------------------
1 | getPrefix();
12 |
13 | //计算分页
14 | $pageSize = 20;
15 | $currentPage = isset($_REQUEST['p']) ? ($_REQUEST['p'] + 0) : 1;
16 |
17 | $all = $db->fetchAll($db->select()->from('table.baidusubmit')
18 | ->order('table.baidusubmit.time', Typecho_Db::SORT_DESC));
19 |
20 | $pageCount = ceil( count($all)/$pageSize );
21 |
22 | $current = $db->fetchAll($db->select()->from('table.baidusubmit')
23 | ->page($currentPage, $pageSize)
24 | ->order('table.baidusubmit.time', Typecho_Db::SORT_DESC));
25 |
26 | //计算分组
27 | $options = Helper::options();
28 |
29 | $pages = $db->fetchAll($db->select()->from('table.contents')
30 | ->where('table.contents.status = ?', 'publish')
31 | ->where('table.contents.created < ?', $options->gmtTime)
32 | ->where('table.contents.type = ?', 'page')
33 | ->order('table.contents.created', Typecho_Db::SORT_DESC));
34 |
35 | $articles = $db->fetchAll($db->select()->from('table.contents')
36 | ->where('table.contents.status = ?', 'publish')
37 | ->where('table.contents.created < ?', $options->gmtTime)
38 | ->where('table.contents.type = ?', 'post')
39 | ->order('table.contents.created', Typecho_Db::SORT_DESC));
40 |
41 | $count = count($pages) + count($articles);
42 |
43 | $group_volume = Helper::options()->plugin('BaiduSubmit')->group;
44 |
45 | $group_num = ceil($count / $group_volume);
46 |
47 |
48 | ?>
49 |
50 |
51 |
52 |
53 |
54 |
82 |
83 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
133 |
153 |
156 |
--------------------------------------------------------------------------------
/Action.php:
--------------------------------------------------------------------------------
1 | plugin('BaiduSubmit')->group;
15 |
16 | $group = isset($_REQUEST['group']) ? ($_REQUEST['group'] + 0) : 1;
17 |
18 | //获取所有链接数组
19 | $url_array = self::gen_all_url();
20 |
21 | $urls = array_slice($url_array, ($group - 1) * $group_volume, $group_volume);
22 |
23 | //设置超时
24 | set_time_limit(600);
25 |
26 | self::post($urls, $group);
27 |
28 | header('Location: ' . $_SERVER['HTTP_REFERER'], false, 302);
29 | exit;
30 | }
31 |
32 | public static function gen_all_url()
33 | {
34 |
35 | $urls = array();
36 |
37 | $db = Typecho_Db::get();
38 | $options = Helper::options();
39 |
40 | $pages = $db->fetchAll($db->select()->from('table.contents')
41 | ->where('table.contents.status = ?', 'publish')
42 | ->where('table.contents.created < ?', $options->gmtTime)
43 | ->where('table.contents.type = ?', 'page')
44 | ->order('table.contents.created', Typecho_Db::SORT_DESC));
45 |
46 | $articles = $db->fetchAll($db->select()->from('table.contents')
47 | ->where('table.contents.status = ?', 'publish')
48 | ->where('table.contents.created < ?', $options->gmtTime)
49 | ->where('table.contents.type = ?', 'post')
50 | ->order('table.contents.created', Typecho_Db::SORT_DESC));
51 |
52 | foreach ($pages AS $page) {
53 | $type = $page['type'];
54 | $routeExists = (NULL != Typecho_Router::get($type));
55 | $page['pathinfo'] = $routeExists ? Typecho_Router::url($type, $page) : '#';
56 | $urls[] = Typecho_Common::url($page['pathinfo'], $options->index);
57 | }
58 | foreach ($articles AS $article) {
59 | $type = $article['type'];
60 | $routeExists = (NULL != Typecho_Router::get($type));
61 | if(!is_null($routeExists)){
62 | $article['categories'] = $db->fetchAll($db->select()->from('table.metas')
63 | ->join('table.relationships', 'table.relationships.mid = table.metas.mid')
64 | ->where('table.relationships.cid = ?', $article['cid'])
65 | ->where('table.metas.type = ?', 'category')
66 | ->order('table.metas.order', Typecho_Db::SORT_ASC));
67 | $article['category'] = urlencode(current(Typecho_Common::arrayFlatten($article['categories'], 'slug')));
68 | $article['slug'] = urlencode($article['slug']);
69 | $article['date'] = new Typecho_Date($article['created']);
70 | $article['year'] = $article['date']->year;
71 | $article['month'] = $article['date']->month;
72 | $article['day'] = $article['date']->day;
73 | }
74 | $article['pathinfo'] = $routeExists ? Typecho_Router::url($type, $article) : '#';
75 | $urls[] = Typecho_Common::url($article['pathinfo'], $options->index);
76 | }
77 |
78 | return $urls;
79 | }
80 |
81 | public static function sitemap()
82 | {
83 | $db = Typecho_Db::get();
84 | $options = Helper::options();
85 |
86 | $bot_list = array(
87 | 'baidu' => '百度',
88 | 'google' => '谷歌',
89 | 'sogou' => '搜狗',
90 | 'youdao' => '有道',
91 | 'soso' => '搜搜',
92 | 'bing' => '必应',
93 | 'yahoo' => '雅虎',
94 | '360' => '360搜索'
95 | );
96 |
97 | $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
98 | foreach ($bot_list as $k => $v) {
99 | if (strpos($useragent, ($k . '')) !== false) {
100 | $log['subject'] = $v;
101 | $log['action'] = '请求';
102 | $log['object'] = 'sitemap';
103 | $log['result'] = '成功';
104 | self::logger($log);
105 | }
106 | }
107 |
108 | $pages = $db->fetchAll($db->select()->from('table.contents')
109 | ->where('table.contents.status = ?', 'publish')
110 | ->where('table.contents.created < ?', $options->gmtTime)
111 | ->where('table.contents.type = ?', 'page')
112 | ->order('table.contents.created', Typecho_Db::SORT_DESC));
113 |
114 | $articles = $db->fetchAll($db->select()->from('table.contents')
115 | ->where('table.contents.status = ?', 'publish')
116 | ->where('table.contents.created < ?', $options->gmtTime)
117 | ->where('table.contents.type = ?', 'post')
118 | ->order('table.contents.created', Typecho_Db::SORT_DESC));
119 |
120 | //changefreq -> always、hourly、daily、weekly、monthly、yearly、never
121 | //priority -> 0.0优先级最低、1.0最高
122 | header("Content-Type: application/xml");
123 | echo "\n";
124 | echo "\n";
125 | foreach ($pages AS $page) {
126 | $type = $page['type'];
127 | $routeExists = (NULL != Typecho_Router::get($type));
128 | $page['pathinfo'] = $routeExists ? Typecho_Router::url($type, $page) : '#';
129 | $page['permalink'] = Typecho_Common::url($page['pathinfo'], $options->index);
130 |
131 | echo "\t\n";
132 | echo "\t\t" . $page['permalink'] . "\n";
133 | echo "\t\t" . date('Y-m-d', $page['modified']) . "\n";
134 | echo "\t\tdaily\n";
135 | echo "\t\t0.8\n";
136 | echo "\t\n";
137 | }
138 | foreach ($articles AS $article) {
139 | $type = $article['type'];
140 | $article['categories'] = $db->fetchAll($db->select()->from('table.metas')
141 | ->join('table.relationships', 'table.relationships.mid = table.metas.mid')
142 | ->where('table.relationships.cid = ?', $article['cid'])
143 | ->where('table.metas.type = ?', 'category')
144 | ->order('table.metas.order', Typecho_Db::SORT_ASC));
145 | $article['category'] = urlencode(current(Typecho_Common::arrayFlatten($article['categories'], 'slug')));
146 | $article['slug'] = urlencode($article['slug']);
147 | $article['date'] = new Typecho_Date($article['created']);
148 | $article['year'] = $article['date']->year;
149 | $article['month'] = $article['date']->month;
150 | $article['day'] = $article['date']->day;
151 | $routeExists = (NULL != Typecho_Router::get($type));
152 | $article['pathinfo'] = $routeExists ? Typecho_Router::url($type, $article) : '#';
153 | $article['permalink'] = Typecho_Common::url($article['pathinfo'], $options->index);
154 |
155 | echo "\t\n";
156 | echo "\t\t" . $article['permalink'] . "\n";
157 | echo "\t\t" . date('Y-m-d', $article['modified']) . "\n";
158 | echo "\t\tdaily\n";
159 | echo "\t\t0.8\n";
160 | echo "\t\n";
161 | }
162 | echo "";
163 | }
164 |
165 | public static function logger($data)
166 | {
167 | $db = Typecho_Db::get();
168 | $db->query($db->insert('table.baidusubmit')
169 | ->rows(array(
170 | 'subject' => $data['subject'],
171 | 'action' => $data['action'],
172 | 'object' => $data['object'],
173 | 'result' => $data['result'],
174 | 'more' => var_export($data['more'], 1),
175 | 'time' => time()
176 | )));
177 | }
178 |
179 |
180 | /**
181 | * 准备数据
182 | * @param $contents 文章内容
183 | * @param $class 调用接口的类
184 | * @throws Typecho_Plugin_Exception
185 | */
186 | public static function send($contents, $class)
187 | {
188 |
189 | //如果文章属性为隐藏或滞后发布
190 | if ('publish' != $contents['visibility'] || $contents['created'] > time()) {
191 | return;
192 | }
193 |
194 | //获取系统配置
195 | $options = Helper::options();
196 |
197 | //判断是否配置好API
198 | if (is_null($options->plugin('BaiduSubmit')->api)) {
199 | throw new Typecho_Plugin_Exception(_t('api未配置'));
200 | }
201 |
202 | //获取文章类型
203 | $type = $contents['type'];
204 |
205 | //获取路由信息
206 | $routeExists = (NULL != Typecho_Router::get($type));
207 |
208 | if(!is_null($routeExists)){
209 | $db = Typecho_Db::get();
210 | $contents['cid'] = $class->cid;
211 | $contents['categories'] = $db->fetchAll($db->select()->from('table.metas')
212 | ->join('table.relationships', 'table.relationships.mid = table.metas.mid')
213 | ->where('table.relationships.cid = ?', $contents['cid'])
214 | ->where('table.metas.type = ?', 'category')
215 | ->order('table.metas.order', Typecho_Db::SORT_ASC));
216 | $contents['category'] = urlencode(current(Typecho_Common::arrayFlatten($contents['categories'], 'slug')));
217 | $contents['slug'] = urlencode($contents['slug']);
218 | $contents['date'] = new Typecho_Date($contents['created']);
219 | $contents['year'] = $contents['date']->year;
220 | $contents['month'] = $contents['date']->month;
221 | $contents['day'] = $contents['date']->day;
222 | }
223 |
224 | //生成永久连接
225 | $path_info = $routeExists ? Typecho_Router::url($type, $contents) : '#';
226 | $permalink = Typecho_Common::url($path_info, $options->index);
227 |
228 | //调用post方法
229 | self::post($permalink);
230 | }
231 |
232 | /**
233 | * 发送数据
234 | * @param $url 准备发送的url
235 | * @param $group 分组信息
236 | */
237 | public static function post($url, $group=null)
238 | {
239 | $options = Helper::options();
240 |
241 | //获取API
242 | $api = $options->plugin('BaiduSubmit')->api;
243 |
244 | //准备数据
245 | if (is_array($url)) {
246 | $urls = $url;
247 | } else {
248 | $urls = array($url);
249 | }
250 |
251 | //日志信息
252 |
253 | $log['subject'] = '我';
254 | $log['action'] = '发送';
255 | $log['object'] = 'URL';
256 |
257 |
258 | if($group) $log['more']['group'] = $group;
259 |
260 | $log['more']['url'] = $urls;
261 |
262 | try {
263 | //为了保证成功调用,老高先做了判断
264 | if (false == Typecho_Http_Client::get()) {
265 | throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使用此功能'));
266 | }
267 |
268 | //发送请求
269 | $http = Typecho_Http_Client::get();
270 | $http->setData(implode("\n", $urls));
271 | $http->setHeader('Content-Type', 'text/plain');
272 | $json = $http->send($api);
273 | $return = json_decode($json, 1);
274 | $log['more']['info'] = $return;
275 | if (isset($return['error'])) {
276 | $log['result'] = '失败';
277 | } else {
278 | $log['result'] = '成功';
279 | }
280 |
281 | } catch (Typecho_Exception $e) {
282 | $log['more']['info'] = $e->getMessage();
283 | $log['result'] = '失败';
284 | }
285 |
286 | self::logger($log);
287 | }
288 |
289 | }
290 |
--------------------------------------------------------------------------------