## 文章發布處理插件
本插件是在插件市場下載后改善的,為了讓發文章的時候更爽!
后臺的默認編輯器是百度編輯器,由于CMF框架暫時是沒有完善好遠程文件下載的方法,所以在本插件中,實現了遠程下載圖片的方法,遠程下載文件的路徑是固定的,可以自行完善。
插件包含功能:自動發布文章,截取文章內容作為摘要,**遠程圖片下載**,內容的首張圖片作為**縮略圖**
CMF插件整體流程:
1,文章保存時候觸發鉤子:
> \app\portal\controller\AdminArticleController.php
public function addPost()
158行: hook('portal_admin_after_save_article', $hookParam);
2,插件實現:
> \plugins\portal_admin_after_save_article
在根目錄下的plugins文件夾里添加插件,插件的名稱自定義;這里與鉤子名稱一致:portal_admin_after_save_article
里面為實現插件的主體文件:PortalAdminAfterSaveArticlePlugin.php
> \plugins\portal_admin_after_save_article\PortalAdminAfterSaveArticlePlugin.php
<?php
namespace plugins\portal_admin_after_save_article;
use cmf\lib\Plugin;
use think\Db;
use app\portal\model\PortalPostModel;
class PortalAdminAfterSaveArticlePlugin extends Plugin
{
public $info = [
'name' => 'PortalAdminAfterSaveArticle',
'title' => '后臺文章保存之后自動處理',
'description' => '自動發布、自動截取文章摘要、遠程圖片下載/自動獲取文章縮略圖',
'status' => 1,
'author' => 'FREE',
'version' => '1.0'
];
//安裝插件
public function install()
{
return true;
}
//卸載插件
public function uninstall()
{
return true;
}
//實現鉤子:portal_admin_after_save_article
public function PortalAdminAfterSaveArticle($hookParam)
{
trace($hookParam, 'error');
$config = $this->getConfig();
$updateData = array();
//只有添加文章時執行自動發布
if ($hookParam['is_add']) {
//是否自動發布
if ($config['auto_publish'] == '1') {
$updateData['post_status'] = 1;
$updateData['published_time'] = time();
}
}
$auto_excerpt = trim($config['auto_excerpt']);
//文章摘要為空
if (trim($hookParam['article']['post_excerpt']) == false && !empty($hookParam['article']['post_content'])) {
//是否自動截取摘要
if (!empty($auto_excerpt)) {
$updateData['post_excerpt'] = $this->_getSummary($hookParam['article']['post_content'], 0, $auto_excerpt);
Db::name("portal_post")->where(['id' => $hookParam['article']['id']])->update($updateData);
}
}
$content="";
//判斷圖片內容是否遠程上傳
if($this->_get_fileType($hookParam['article']['post_content'])){
//創建上傳目錄(絕對路徑)
$date = date("Ymd");
$uploadPath = WEB_ROOT . 'upload' . DIRECTORY_SEPARATOR . "images" . DIRECTORY_SEPARATOR . $date . DIRECTORY_SEPARATOR;
if (!file_exists($uploadPath)) {
mkdir("$uploadPath", 0777, true);
}
//相對路徑(前臺用)
$savePath = "/upload/images/" . $date . "/";
//獲取編輯器內容,5.1.4以上版本需要添加反轉義函數
$content = htmlspecialchars_decode($hookParam['article']['post_content']);
$title_id= uniqid();
$preg_img="/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.jpeg|\.png]))[\'|\"].*?[\/]?>/";
preg_match_all($preg_img, $content,$arr_img); //正則獲取所有圖片
//print_r($arr_img);
//遍歷替換所有的圖片 //$arr_img[1] 獲取所有圖片路徑
//_get_image_byurl 實現遠程圖片本地化
foreach ($arr_img[1] as $imgid=>$v){
$img_id = $title_id."_".$imgid.".jpg";
$content= str_replace($v, $savePath.$img_id,$content);
$this->_get_image_byurl($v,$img_id,$savePath);
}
//更新內容
if (!empty($content)) {
Db::name("portal_post")->where(['id' => $hookParam['article']['id']])->update(['post_content'=> $content]);
}
}
//自動獲取縮略圖
if ($config['auto_thumbnail'] == '1') {
if (empty($hookParam['article']['more']['thumbnail'])) {
$data=[];
$data['id']=$hookParam['article']['id'];
$content1 = empty( $content ) ? $hookParam['article']['post_content'] : $content ;
$pattern1 = "/\<img.*?src\=\"(.*?)\"[^>]*>/i";
preg_match_all($pattern1,$content1 ,$matchContent1);
if(!empty($matchContent1[1][0])){
$rurl = $matchContent1[1][0];
$data['more']['thumbnail']=$rurl;
$post = new PortalPostModel();
$post->allowField(true)->isUpdate(true)->data($data, true)->save();
}
}
}
}
/**
* [判斷圖片是否遠程圖片]
* @param [string] $content [文章內容]
* @return [bool] [true為遠程,false為本地]
*/
private function _get_fileType($content){
$pattern = "/\<img.*?src\=\"(.*?)\"[^>]*>/i";
preg_match_all($pattern,$content,$matches);
// var_dump($matches); // 得到匹配成功的二維數組,0為完整圖片,1為圖片url ; 判斷第一個圖片是否遠程圖片
$url = $matches[1][0];
$preg = "/^http(s)?:\\/\\/.+/";
if(preg_match($preg,$url))
{
return true;
}else //本地
{
return false;
}
}
/**
* 文章簡介截取方法
* @param $content 文章內容
* @param int $s 開始截取位置
* @param int $e 截取結束位置
* @param string $char 字符編碼
* @return string
*/
private function _getSummary($content, $s = 0, $e = 100, $char = 'utf-8')
{
if (empty($content)) {
return '';
}
$newContent = strip_tags(htmlspecialchars_decode($content));
$newContent = str_replace(' ', '', $newContent);
$patternArr = array('/\s/', '/ /');
$replaceArr = array('', '');
$newContent = preg_replace($patternArr, $replaceArr, $newContent);
$newContent = mb_substr($newContent, $s, $e, $char);
return trim($newContent);
}
/**
* [get_image_byurl 下載遠程圖片到本地]
* @param [type] $url [原始圖片URL]
* @param [type] $img_name [本地圖片名稱]
* @param string $filename [本地圖片存放地址]
* @return [type] [文件名]
*/
function get_image_byurl($url,$img_name,$filename="") {
if ($url == "") { return false; }
$ext = strrchr($url, "."); //得到圖片的擴展名
if($ext != ".gif" && $ext != ".jpg" && $ext != ".bmp") { $ext = ".jpg"; }
if($filename == "") { $filename ="./upload/images/".$img_name; }
//以流的形式保存圖片
$return_content = $this->http_get_data($url);
$fp= @fopen($filename,"a"); //將文件綁定到流
fwrite($fp,$return_content); //寫入文件
@fclose($write_fd);
return($filename); //返回文件名
}
/**
* [http_get_data 遠程請求獲取圖片]
* @param [type] $url [圖片URL]
* @return [type] [圖片二進制流]
*/
function http_get_data($url) {
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt ( $ch, CURLOPT_URL, $url );
ob_start ();
curl_exec ( $ch );
$return_content = ob_get_contents ();
ob_end_clean ();
$return_code = curl_getinfo ( $ch, CURLINFO_HTTP_CODE );
return $return_content;
}
}
插件的獨立配置文件,供給后臺設置
> \plugins\portal_admin_after_save_article\config.php
<?php
return array(
'auto_publish' => array(// 在后臺插件配置表單中的鍵名 ,會是config[text]
'title' => '文章自動發布', // 表單的label標題
'type' => 'radio',// 表單的類型:text,password,textarea,checkbox,radio,select等
'options' => [
'1' => '是',
'0' => '否'
],
'value' => '1',// 表單的默認值
'tip' => '選擇是,文章保存之后自動發布,無需再執行"編輯->發布->保存"流程' //表單的幫助提示
),
'auto_excerpt' => array(// 在后臺插件配置表單中的鍵名 ,會是config[text]
'title' => '自動截取文章摘要', // 表單的label標題
'type' => 'text',// 表單的類型:text,password,textarea,checkbox,radio,select等
'value' => '100',// 表單的默認值
'tip' => '截取文章內容的字符數,留空則不截取' //表單的幫助提示
),
'auto_thumbnail' => array(// 在后臺插件配置表單中的鍵名 ,會是config[text]
'title' => '自動生成文章縮略圖', // 表單的label標題
'type' => 'radio',// 表單的類型:text,password,textarea,checkbox,radio,select等
'options' => [
'1' => '是',
'0' => '否'
],
'value' => '1',// 表單的默認值
'tip' => '選擇是,文章保存之后自動獲取正文第一個圖片作為縮略圖' //表單的幫助提示
),
);
插件安裝的方法:
將上面的文件按照路徑安排好,在后臺插件列表里安裝插件,發表文章后就會自動執行上面的方法了。