web-dev-qa-db-ja.com

既に使用されている注目画像を自動設定する機能

私はこれを考え出すことからどこから始めればいいのかさえ知りません……

Functions.phpのためのこの関数は投稿内の最初の添付画像を取得し、それを注目画像として設定します。問題は、既に別の投稿に添付されている場合、その画像は添付されないということです。私はこれを何度もテストしました。

すでに別の投稿に添付されている画像を新しい投稿のおすすめ画像として設定できるようにするには、この関数をどのように変更しますか?

    function wpse127196_auto_set_featured_image() {
              global $post;
              $featured_image_exists = has_post_thumbnail($post->ID);
                  if (!$featured_image_exists)  {
                  $attached_image = get_children(
"post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
           if ($attached_image) {
                  foreach ($attached_image as $attachment_id => $attachment) {
                                set_post_thumbnail($post->ID, $attachment_id);
                                    }
                               }
                            }
          }
    add_action('save_post', 'wpse127196_auto_set_featured_image');
    add_action('draft_to_publish', 'wpse127196_auto_set_featured_image');
    add_action('new_to_publish', 'wpse127196_auto_set_featured_image');
    add_action('pending_to_publish', 'wpse127196_auto_set_featured_image');
    add_action('future_to_publish', 'wpse127196_auto_set_featured_image');
2
markratledge

まず第一に、私はあなたが5つの異なるアクションをフックする必要がある理由を理解することができません:save_postは十分です:それはポストパブリッシュとアップデートで呼ばれます。

その後、投稿した関数は投稿コンテンツの画像を取得できませんが、現在の投稿のである最初の画像を取得します。

次の場合、画像は投稿の子になります。

  • 投稿編集画面からアップロードされます(投稿コンテンツエディタの上にある[メディアの追加]ボタンを使用)。
  • メディアページからアップロードされ、初めて投稿に挿入されます。

ただし、投稿とメディアの関係は1対多です。投稿には多くのメディアの子を含めることができますが、メディアには1つの親しか持つことができません。

これは、画像がすでに投稿に添付されている(投稿の子である)場合、その画像が2(またはそれ以上)の投稿の子になることはできないため、関数が機能しない理由です。

したがって、投稿コンテンツの最初の画像を取得する場合は、投稿コンテンツを調べて最初の画像を抽出し、次にその画像から画像IDを取得し、最後にそのIDを投稿サムネイルとして使用する必要があります。

add_action('save_post', 'wpse127196_auto_set_featured_image', 10, 2);

function wpse127196_auto_set_featured_image( $postid, $post ) {
  // do work only if there is no featured image already
  // and no need to rely on global post: the function receive
  // post id and post object as arguments
  if ( ! has_post_thumbnail($postid) ) {
     // get the url of first image in post content
     $image = wpse127196_get_first_image( $post->post_content);
     if ( ! empty($image) ) {
        // get the image id from the url
        $img_id =  wpse127196_get_img_id_from_url( $image );
        if ( (int) $img_id > 0 ) {
          // finally set post thumbnail
          set_post_thumbnail($postid, $img_id );
        }
     }
  }
}

ご覧のとおり、上の関数ではwpse127196_get_first_imagewpse127196_get_img_id_from_urlの2つの関数が使用されています。

1つ目は、コンテンツから抽出してイメージを作成する方法です。おそらく最も堅実なのは、HTMLパーサーを使うことです( Googleには )。もっと簡単で手頃な方法は正規表現を使うことです。

簡単にするために、ここでは正規表現を使用します。

function wpse127196_get_first_image( $text = '' ) {
  if ( is_string($text) && ! empty($text) ) {
    $m = array();
    preg_match_all('#src=["\']([^"\']*\.jpg|jpeg|gif|png)["\']#i' , $text, $m);
    if ( isset($m[1]) && ! empty($m[1]) ) {
       $path = wp_upload_dir();
       foreach( $m[1] as $url ) {
         if ( false !== strpos( $url, $path['baseurl'] ) ) { // skip external images
           return $url;
         }
       }
    }
  }
}

Urlから始まるidを取得する関数は、 から来ています

function wpse127196_get_img_id_from_url( $url ) {
  $id = 0;
  if ( filter_var($url, FILTER_VALIDATE_URL) ) {
    $upload_dir_paths = wp_upload_dir();
    // skip external images
    if ( false !== strpos( $url, $upload_dir_paths['baseurl'] ) ) {
      global $wpdb;
      // If this is the URL of an auto-generated thumbnail
      // get the URL of the original image
      $url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $url );
      // Remove the upload path base directory from the attachment URL
      $url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $url );
      // Finally, run a custom database query to get the attachment ID from URL
      $id = $wpdb->get_var( $wpdb->prepare(
        "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta 
        WHERE wposts.ID = wpostmeta.post_id 
        AND wpostmeta.meta_key = '_wp_attached_file' 
        AND wpostmeta.meta_value = '%s' 
        AND wposts.post_type = 'attachment'", $url
      ) );
     }
  }
  return $id;
}
1
gmazzap