[WordPress] 抓取文章第一張媒體庫圖片設定為封面精選圖片

本篇文章更新時間:2020/06/24
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~


好久沒有碰到值得筆記的事,今天終於來一個!需求是希望批次把沒有上精選圖片的文章給自動設定,條件是文章中的第一張圖。

過去曾幫同事把 Blogger 的文轉到 WordPress 自架站上,但發現網傳的解法沒有轉完整,圖片還是在 Blogger 空間,這樣半調子實在無法接受,於是寫了一段程式處理: Blogger 文章匯入使用內建匯入工具

邏輯是掃描文章圖片,把不在媒體庫的圖都載回來關聯文章,沒有精選封面圖片的文順便設定上。

對,其實可以說是本篇的進階處理方式~ 調整後的程式如下: Gist

<?php
include 'wp-load.php';
set_time_limit(0);
ini_set('memory_limit', '256M');

add_action('after_setup_theme', function () {
    add_filter('intermediate_image_sizes', '__return_empty_array');
    add_filter('wp_get_attachment_image_src', function ($image, $attachment_id, $size, $icon) {
        // get a thumbnail or intermediate image if there is one
        $image = image_downsize($attachment_id, 'full');
        if (!$image) {
            $src = false;

            if ($icon && $src = wp_mime_type_icon($attachment_id)) {
                /** This filter is documented in wp-includes/post.php */
                $icon_dir = apply_filters('icon_dir', ABSPATH . WPINC . '/images/media');

                $src_file              = $icon_dir . '/' . wp_basename($src);
                @list($width, $height) = getimagesize($src_file);
            }

            if ($src && $width && $height) {
                $image = array($src, $width, $height);
            }
        }
        return $image;
    }, 999, 4);
});

function parsing_image($post_id, $content) {
    preg_match_all('/<img\s+.*?src=[\"\'](http[s]{0,1}\:\/\/?[^\"\' >]*)[\"\']?[^>]*>/i', $content, $matches);
    $images = $matches[1];
    mxp_import_image($post_id, $images);
    return $content;
}
function mxp_import_image($post_id, $imgs) {
    require_once ABSPATH . 'wp-admin/includes/media.php';
    require_once ABSPATH . 'wp-admin/includes/file.php';
    require_once ABSPATH . 'wp-admin/includes/image.php';
    global $wpdb;
    $upload_dir  = wp_upload_dir();
    $img_post_id = 0;
    for ($i = 0; $i < count($imgs); ++$i) {
        if ($img_post_id == 0) {
            $attachment_id = $wpdb->get_results(
                $wpdb->prepare(
                    "SELECT ID FROM $wpdb->posts WHERE guid LIKE %s", '%' . pathinfo(str_replace($upload_dir['baseurl'] . "/", "", $imgs[$i]), PATHINFO_FILENAME) . '%'
                ),
                ARRAY_A
            );
            if (isset($attachment_id[0]['ID'])) {
                $img_post_id = $attachment_id[0]['ID'];
            }
        }
    }
    //有存特色圖片就不改了
    if (!has_post_thumbnail($post_id)) {
        echo "沒特色圖片,開始匯入操作".PHP_EOL;
        if ($img_post_id == 0) {
            // 如果沒找到半張媒體庫圖片,自行指定
            $img_post_id = 999; //填入媒體庫圖片的 Post ID
            echo "找不到媒體庫圖片,使用替代圖片:{$img_post_id}".PHP_EOL;
        }
        set_post_thumbnail($post_id, $img_post_id);
    }

}
global $wpdb;
$querystr = "SELECT ID,post_content FROM $wpdb->posts WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' AND $wpdb->posts.post_date < NOW() ORDER BY $wpdb->posts.post_date DESC";

$posts = $wpdb->get_results($querystr, ARRAY_A);

foreach ($posts as $key => $post) {
    $post_id      = $post['ID'];
    $post_content = $post['post_content'];
    //匯入圖片
    $update_attachment_post = array(
        'ID'           => $post_id,
        'post_content' => parsing_image($post_id, $post_content),
    );
    // $update_attachment_post['post_excerpt'] = wp_trim_words($update_attachment_post['post_content'], 200, '...');
    $upid = wp_update_post($update_attachment_post);
    echo $post_id . " => 完成匯入!" . PHP_EOL;
}

使用方式

執行此項操作會對資料庫進行變更,建議操作前先完整備份資料庫一次!

將上述程式存成 xxx.php (xxx 自行命名),然後放置於 WordPress 根目錄下,使用:

  1. 指令執行 php -f xxx.php
  2. 瀏覽器執行,透過瀏覽器瀏覽該檔案觸發

61 行的圖片 Post ID 設定是如果文內沒圖,可以手動指定一組預設設定。

結語

感謝某位匿名人士贊助此需求,沒有他就沒有這文了XD

本應用簡化不少,不處理下載遠端圖片回本地也不做其他多餘處理,僅判斷是否有精選圖片,沒有就套用媒體庫的圖為封面。嚴格來說「第一張」不一定正確,是「第一張媒體庫的圖」才正確,所以外連的圖不會被設定為封面且若圖片放置於其他空間,處理的方式就不同囉~


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[//////////____30%_________]

參與討論

1 則留言

  1. 非常感謝筆者的分享以及匿名人士贊助才有了這篇文XDDD
    獲益良多~~~~~~~~

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *