TaoLer/app/admin/controller/Seo.php
2022-04-17 17:09:19 +08:00

268 lines
8.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/*
* @Author: TaoLer <alipey_tao@qq.com>
* @Date: 2022-04-13 09:54:31
* @LastEditTime: 2022-04-17 16:55:13
* @LastEditors: TaoLer
* @Description: 搜索引擎SEO优化设置
* @FilePath: \TaoLer\app\admin\controller\Seo.php
* Copyright (c) 2020~2022 http://www.aieok.com All rights reserved.
*/
declare(strict_types=1);
namespace app\admin\controller;
use app\common\controller\AdminController;
use think\facade\View;
use think\facade\Request;
use think\facade\Db;
use app\common\lib\SetArr;
class Seo extends AdminController
{
public function index()
{
if(is_file($rob = public_path().'robots.txt')){
$robots = file_get_contents($rob);
} else {
$robots = '';
}
View::assign('robots',$robots);
return View::fetch();
}
public function push()
{
if(empty(config('taoler.baidu.push_api'))) return json(['code'=>-1,'msg'=>'请先配置接口push_api']);
$urls = [];
$artAllId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->column('id');
foreach($artAllId as $aid) {
$urls[] = $this->getRouteUrl($aid);
}
$api = config('taoler.baidu.push_api');
$ch = curl_init();
$options = array(
CURLOPT_URL => $api,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => implode("\n", $urls),
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
if($result == false) {
return json(['code'=>-1,'msg'=>'接口失败']);
}
$res = stripos($result,'error');
$data = json_decode($result);
if($res !== false) {
return json(['code'=>-1,'msg'=>$data->message]);
};
return json(['code'=>0,'msg'=>'成功推送'.$data->success.'条,今天剩余'.$data->remain]);
}
public function config()
{
//
$baidu = [];
$data = Request::only(['client_id','client_secret','push_api']);
foreach($data as $k => $v) {
if($v !== ''){
if($k == 'push_api') {
$baidu[$k] = "'$v'";
} else {
$baidu[$k] = $v;
}
}
}
$res = (new SetArr('taoler'))::edit([
'baidu' => $baidu,
]);
if($res == true){
return json(['code'=>0,'msg'=>'设置成功']);
}
}
/**
* 百度谷歌sitemap生成xml文件
*
* @return void
*/
public function map()
{
$data = Request::only(['map_num','map_time','map_level']);
// 写文件字符串
$str = '';
// 标记第一次调用写ID
$flag= true;
// 写ID
$w_id = '';
// 新文件编号
$i = 1;
// 获取public下所有xml文件
$newFile = $this->getXmlFile(public_path());
// 没有xml文件时不存在重写
if(empty($newFile)) {
$rewrite = false;
} else {
$xmlFile = end($newFile);
$strFile = file_get_contents(public_path().$xmlFile);
$num = substr_count($strFile, '<url>');
// 是否有需要追加在文件,判断最新文件是否未写满
$rewrite = $num < $data['map_num'] ? true : false;
}
if($rewrite){
// 需要追加的数量
$limit = (int) $data['map_num'] - $num;
$name = pathinfo($xmlFile,PATHINFO_FILENAME);
$arr = explode('_', $name);
// 检验当天,避免重复生成
if($arr[0] == date('Y-d-m'))
{
$i = $arr[1] + 1;
}
} else {
$limit = (int) $data['map_num'];
}
// 最新ID
$maxId = Db::name('article')->where(['delete_time'=>0,'status'=>1])->max('id');
do
{
$wr_id = $flag ? config('taoler.sitemap.write_id') : $w_id;
$artAllId = Db::name('article')
->where(['delete_time'=>0,'status'=>1])
->where('id', '>', (int) $wr_id)
->order('id','asc')->limit($limit)->column('update_time','id');
if(empty($artAllId)) {
return json(['code'=>-1,'msg'=>'本次无需生成']);
} else {
// 本次最新文件ID
$last_id = array_key_last($artAllId);
// 循环拼接文件字符串
foreach($artAllId as $aid => $uptime) {
// url生成
$url = $this->getRouteUrl($aid);
$time = date('Y-m-d', $uptime);
// 组装字符串
$str .= <<<STR
<url>
<loc>$url</loc>
<lastmod>$time</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>\n
STR;
}
// 写文件
if($rewrite){
// 写入旧xml文件
$reps = $str.'</urlset>';
$xml = preg_replace('/<\/urlset>/', $reps, $strFile);
$res = file_put_contents(public_path().$xmlFile, $xml);
if($res == false){
return json(['code'=>-1,'msg'=>$xmlFile.'写入失败']);
}
$limit = $data['map_num'];
$rewrite = false;
} else {
// 生成新xml
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?> <!-- XML文件需以utf-8编码-->
<urlset>\n$str</urlset>
XML;
$res = file_put_contents(public_path().date('Y-m-d').'_'.$i.'.xml', $xml);
if($res == false){
return json(['code'=>-1,'msg'=>date('Y-m-d').'_'.$i.'.xml写入失败']);
}
}
// 重置标记内容
$str = '';
$i++;
$w_id = $last_id;
$flag = false;
}
}
while($last_id < (int) $maxId);
// 写配置标记最后写入ID
$res = (new SetArr('taoler'))::edit([
'sitemap' => [
'map_num' => $data['map_num'],
'write_id' => $last_id,
],
]);
if($res == false){
return json(['code'=>-1,'msg'=>'写xml配置失败']);
}
return json(['code'=>0,'msg'=>'生成xml成功']);
}
/**
* 返回public目录下xml名称数组
*
* @param string $dir
* @return array
*/
public function getXmlFile(string $dir) : array
{
$arr = [];
$files = array_diff(scandir($dir), array('.', '..'));
foreach ($files as $file) {
if(is_file("$dir/$file") && !is_link($dir) && (pathinfo("$dir/$file", PATHINFO_EXTENSION)) == 'xml')
{
$arr[] = "$file";
}
}
return $arr;
}
/**
* 生成robots
*
* @return void
*/
public function robots()
{
if(Request::isPost()){
$txt = input('robots');
$xmlArr = $this->getXmlFile(public_path());
foreach($xmlArr as $v) {
$res = stripos($txt, $v);
if($res == false){
$map = $this->getIndexUrl().'/'.$v;
$txt .= "\nsitemap:".$map;
}
}
$res = file_put_contents(public_path().'robots.txt',$txt);
if($res == false){
return json(['code'=>-1,'msg'=>$v.'写入失败']);
}
return json(['code'=>0,'msg'=>'设置成功']);
}
}
/**
* 获取文章链接地址
*
* @param integer $aid
* @return string
*/
protected function getRouteUrl(int $aid) : string
{
$indexUrl = $this->getIndexUrl();
$artUrl = (string) url('detail_id', ['id' => $aid]);
if(empty(config('app.domain_bind'))) {
// 未绑定域名
$url = $indexUrl . str_replace('admin','index',$artUrl);
} else {
// 单独绑定域名
$url = $indexUrl . $artUrl;
}
return $url;
}
}