WordPress教程

WordPress 自动将文章里复制粘贴的外链图片本地化到媒体库

阿里云

我们在通过 wp 发布文章时经常会复制别处的文章,文章里通常也带有图片,那么如何把图片粘贴过来的时候自动本地化上传到媒体库呢?

因为最近在给一个客户开发一个自动本地化+自动水印+自动 FTP 上传到另一台服务器的功能,所以在这里给大家说明一下。

也想出现在这里?联系我们
创客主机
  1. /**
  2. * 钩子函数:将post_content中本站服务器域名外的img上传至服务器并替换url
  3. *
  4. * @param Int $post_id
  5. * @param Object $post
  6. *
  7. */
  8. function ecp_save_post($post_id, $post) {
  9. // wordpress 全局变量 wpdb类
  10. global $wpdb;
  11. // 只有在点击发布/更新时才执行以下动作
  12. if($post->post_status == 'publish') {
  13. // 匹配<img>、src,存入$matches数组,
  14. $p = '/<img.*[\s]src=[\"|\'](.*)[\"|\'].*>/iU';
  15. $num = preg_match_all($p, $post->post_content, $matches);
  16.  
  17. if ($num) {
  18. // 本地上传路径信息(数组),用来构造url
  19. $wp_upload_dir = wp_upload_dir();
  20.  
  21. // 脚本执行不限制时间
  22. set_time_limit(0);
  23.  
  24. // 构造curl,配置参数
  25. $ch = curl_init();
  26. curl_setopt($ch, CURLOPT_HEADER, false);
  27. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  28. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  29. // 抓取时如果发生301,302跳转,则进行跳转抓取
  30. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  31. // 最多跳转20次
  32. curl_setopt($ch, CURLOPT_MAXREDIRS,20);
  33. // 发起连接前最长等待时间
  34. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  35.  
  36. $ecp_options = $_SERVER['HTTP_HOST'];
  37.  
  38.  
  39. foreach ($matches[1] as $src) {
  40. if (isset($src) && strpos($src, $ecp_options) === false) {
  41. // 如果图片域名不是本站域名
  42.  
  43. // 检查src中的url有无扩展名,没有则重新给定文件名
  44. // 注意:如果url中有扩展名但格式为webp,那么返回的file_info数组为 ['ext' =>'','type' =>'']
  45. $file_info = wp_check_filetype(basename($src), null);
  46. if ($file_info['ext'] == false) {
  47. // 无扩展名和webp格式的图片会被作为无扩展名文件处理
  48. date_default_timezone_set('PRC');
  49. $file_name = date('YmdHis-').dechex(mt_rand(100000, 999999)).'.tmp';
  50. } else {
  51. // 有扩展名的图片重新给定文件名防止与本地文件名冲突
  52. $file_name = dechex(mt_rand(100000, 999999)) . '-' . basename($src);
  53. }
  54.  
  55. // 抓取图片, 将图片写入本地文件
  56. curl_setopt($ch, CURLOPT_URL, $src);
  57. $file_path = $wp_upload_dir['path'] . '/' . $file_name;
  58. $img = fopen($file_path, 'wb');
  59. // curl写入$img
  60. curl_setopt($ch, CURLOPT_FILE, $img);
  61. $img_data = curl_exec($ch);
  62. fclose($img);
  63.  
  64. if (file_exists($file_path) && filesize($file_path) > 0) {
  65. // 将扩展名为tmp和webp的图片转换为jpeg文件并重命名
  66. $t = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
  67. $arr = explode('/', $t);
  68. // 对url地址中没有扩展名或扩展名为webp的图片进行处理
  69. if (pathinfo($file_path, PATHINFO_EXTENSION) == 'tmp') {
  70. $file_path = ecp_handle_ext($file_path, $arr[1], $wp_upload_dir['path'], $file_name, 'tmp');
  71. } elseif (pathinfo($file_path, PATHINFO_EXTENSION) == 'webp') {
  72. $file_path = ecp_handle_ext($file_path, $arr[1], $wp_upload_dir['path'], $file_name, 'webp');
  73. }
  74.  
  75. // 替换文章内容中的src
  76. $post->post_content = str_replace($src, $wp_upload_dir['url'] . '/' . basename($file_path), $post->post_content);
  77. // 构造附件post参数并插入媒体库(作为一个post插入到数据库)
  78. $attachment = ecp_get_attachment_post(basename($file_path), $wp_upload_dir['url'] . '/' . basename($file_path));
  79. // 生成并更新图片的metadata信息
  80. $attach_id = wp_insert_attachment($attachment, ltrim($wp_upload_dir['subdir'] . '/' . basename($file_path), '/'), 0);
  81. $attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
  82. // 直接调用wordpress函数,将metadata信息写入数据库
  83. $ss = wp_update_attachment_metadata($attach_id, $attach_data);
  84. }
  85. }
  86. }
  87. curl_close($ch);
  88.  
  89. // 更新posts数据表的post_content字段
  90. $wpdb->update( $wpdb->posts, array('post_content' => $post->post_content), array('ID' => $post->ID));
  91. }
  92. }
  93. }
  94.  
  95. /**
  96. * 处理没有扩展名的图片:转换格式或更改扩展名
  97. * @param string $file 图片本地绝对路径
  98. * @param string $type 图片mimetype
  99. * @param string $file_dir 图片在本地的文件夹
  100. * @param string $file_name 图片名称
  101. * @param string $ext 图片扩展名
  102. * @return string 处理后的本地图片绝对路径
  103. */
  104. function ecp_handle_ext($file, $type, $file_dir, $file_name, $ext) {
  105. switch ($ext) {
  106. case 'tmp':
  107. if (rename($file, str_replace('tmp', $type, $file))) {
  108. if ('webp' == $type) {
  109. // 将webp格式的图片转换为jpeg格式
  110. return ecp_image_convert('webp', 'jpeg', $file_dir . '/' . str_replace('tmp', $type, $file_name));
  111. }
  112. return $file_dir . '/' . str_replace('tmp', $type, $file_name);
  113. }
  114. case 'webp':
  115. if ('webp' == $type) {
  116. // 将webp格式的图片转换为jpeg格式
  117. return ecp_image_convert('webp', 'jpeg', $file);
  118. } else {
  119. if (rename($file, str_replace('webp', $type, $file))) {
  120. return $file_dir . '/' . str_replace('webp', $type, $file_name);
  121. }
  122. }
  123. default:
  124. return $file;
  125. }
  126. }
  127.  
  128. /**
  129. * 图片格式转换,暂只能从webp转换为jpeg
  130. *
  131. * @param string $from
  132. * @param string $to
  133. * @param string $image 图片本地绝对路径
  134. * @return string 转换后的图片绝对路径
  135. */
  136. function ecp_image_convert($from='webp', $to='jpeg', $image) {
  137. // 加载 WebP 文件
  138. $im = imagecreatefromwebp($image);
  139. // 以 100% 的质量转换成 jpeg 格式并将原webp格式文件删除
  140. if (imagejpeg($im, str_replace('webp', 'jpeg', $image), 100)) {
  141. try {
  142. unlink($image);
  143. } catch (Exception $e) {
  144. $error_msg = sprintf('Error removing local file %s: %s', $image,
  145. $e->getMessage());
  146. error_log($error_msg);
  147. }
  148. }
  149. imagedestroy($im);
  150.  
  151. return str_replace('webp', 'jpeg', $image);
  152. }
  153.  
  154. /**
  155. * 构造图片post参数
  156. *
  157. * @param string $filename
  158. * @param string $url
  159. * @return array 图片post参数数组
  160. */
  161. function ecp_get_attachment_post($filename, $url) {
  162. $file_info = wp_check_filetype($filename, null);
  163. return array(
  164. 'guid' => $url,
  165. 'post_type' => 'attachement',
  166. 'post_mime_type' => $file_info['type'],
  167. 'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
  168. 'post_content' => '',
  169. 'post_status' => 'inherit'
  170. );
  171. }
  172.  
  173. // 钩子, 发布/草稿/预览时触发
  174. add_action('save_post', 'ecp_save_post', 120, 2);

只要将以上代码添加到你主题的 functions.php 文件里即可,或者可以直接安装插件 Easy copy paste。

WordPress 自动将文章里复制粘贴的外链图片本地化到媒体库

已有 193 人购买
查看演示升级 VIP立刻购买

收藏
(0)

发表回复

热销模板

Ashade - 作品展示摄影相册WordPress汉化主题
LensNews

本站承接 WordPress / PbootCMS / DedeCMS 等
系统建站、仿站、开发、定制等业务!