WordPress メディアライブラリから指定ポストの画像を一括取得する

WordPress Related Post for Japanese の関連に画像を出力してみた試験をしたときに「SQL で一括~」なことを書いていたら、yuriko さんが SQL を書いてくださいました。 早速試させていただいたところ、みごとに一発抽出できました。 🙂

yuriko さんコメント

Yuriko.Net 旅行記の携帯版が似たようなことやっています (各投稿に属する画像を1枚引っぱってきて表示)。わたしも正攻法でやっていて、重たいとは思いませんでしたが、以下のようにして一発取りしてみました。

オリジナルは上記のリンクから参照してください。(コメント欄のコード変換がおかしくて、見づらくなってごめんなさい)

試験的に SQL をとりださせていただいて実行してみました。 a.post_parent に対する IN 句が一括指定する post_id です。

SELECT
        p.post_parent AS post_parent
        ,p.ID AS ID
        ,p.post_title AS title
        ,m.meta_value AS FILE
    FROM
        wp_posts AS p
        ,wp_postmeta AS m
    WHERE
        p.ID = m.post_id
        AND p.post_parent IN (
            641
            ,639
            ,635
            ,629
            ,622
            ,615
            ,602
            ,593
            ,591
            ,101
        )
        AND (
            LOCATE(
                'image/'
                ,p.post_mime_type
            ) = 1
            OR (
                LOCATE(
                    'import'
                    ,p.post_mime_type
                ) = 1
                AND
                    RIGHT (
                        m.meta_value
                        ,4
                    ) IN (
                        '.jpg'
                        ,'jpeg'
                        ,'.gif'
                        ,'.png'
                    )
            )
        )
        AND m.meta_key = '_wp_attached_file'
    ORDER BY
        post_parent

う~ん、すらばしい。 これでループ回さなくてもいっきにとれます。 ありがとうございました。 🙂

さて、つれづれと SQL の結果をみていて気がついたのですが・・・。

guid01

あれ、画像ファイルのフルパスとそうでないのが混在している…? 全然ソース見てないですがどうも 2.7 を境にして変わっている気がしました。

wp-kougabu では、画像の URL を取得するのに別の (wp)_posts の guid というカラムを使っているのですが、たしかこの guid というカラムは記事を一意に特定するという意味だけでその記事(画像)の URL を表すものでは無かった記憶があります。(ここを URL として使うとブログ引っ越しでホスト名とか変わると 置換しないといけない)

とおもいつつ、面倒だったのでとりあえず guid 使ってたのですが、なおさないかんかなと思いつつソースをみてみる。

   1: function wp_get_attachment_url( $post_id = 0 ) {
   2:     $post_id = (int) $post_id;
   3:     if ( !$post =& get_post( $post_id ) )
   4:         return false;
   5:  
   6:     $url = '';
   7:     if ( $file = get_post_meta( $post->ID, '_wp_attached_file', true) ) { //Get attached file
   8:         if ( ($uploads = wp_upload_dir()) && false === $uploads['error'] ) { //Get upload directory
   9:             if ( 0 === strpos($file, $uploads['basedir']) ) //Check that the upload base exists in the file location
  10:                 $url = str_replace($uploads['basedir'], $uploads['baseurl'], $file); //replace file location with url location
  11:         }
  12:     }
  13:  
  14:     if ( empty($url) ) //If any of the above options failed, Fallback on the GUID as used pre-2.7, not recomended to rely upon this.
  15:         $url = get_the_guid( $post->ID );
  16:  
  17:     if ( 'attachment' != $post->post_type || empty($url) )
  18:         return false;
  19:  
  20:     return apply_filters( 'wp_get_attachment_url', $url, $post->ID );
  21: }

ん、フルパスで入ってないと guid 使われる?

If any of the above options failed, Fallback on the GUID as used pre-2.7, not recomended to rely upon this.

んんん?

アップロードディレクトリの設定をかえたりしたことを考えるとフルパス格納じゃないほうが正しい気がしますが、 URL は guid を使ってる??

現在また深夜、ねぼけて違うところみてるいる可能性も高いです。 どれが本当なんだろうか。。 継続審議でお願いいたします。。 Zzz..

WordPress メディアライブラリから指定ポストの画像を一括取得する」への4件のフィードバック

  1. あれ、画像ファイルのフルパスとそうでないのが混在している…? 全然ソース見てないですがどうも 2.7 を境にして変わっている気がしました。

    変ですね。ウチでは一貫してフルパスでした。旅行記は ME 2.0.7から使い続けていますが、当時からそうなっています。相対パスの可能性があるなら、旅行記用携帯テーマは修正が必要です (1.61-rc1 配布してしまったのに)。

    フルパスで入ってなかったら guid を使うというのは実装として変ですね。相対パスだったら $uploads[‘baseurl’] に相対パスをくっつける、のでよい気がしますが……。

  2. おはようございます。 🙂

    ありゃ、フルパスですか!

    朝起きて、普段 xmlrpc 投稿しているせいかなとおもい、素の 2.7 でフラッシュアップローダを使い .jpg 画像をアップロードしてみたところ、 (wp)_postmeta の _wp_attached_file はアップロードディレクトリからの相対パスになりました。(”日付整理”してもしなくても同じのようです)

    謎ですね。。

    にしても、guid 使われるのは妙だな、、とおもって 2.7.1 みてみたら、なにやら修正されて相対パスなら、$uploads[‘baseurl’] くっつけるように変わっているみたいです。(笑

  3. うちはフラッシュアップローダを使ったことがないからかもしれません (Safari はブラウザアップローダになります)。とりあえず、2.7.1 で改修されているので問題なさそうですね。

    あと、SQL ですが、

    ) IN (
    '.jpg'
    ,'.jpeg'
    ,'.gif'
    ,'.png'
    )

    RIGHT 関数で4文字取り出した結果と比較しているので ‘.jpeg’ だとマッチされません。元通り ‘jpeg’ にしておいてください。まあ、最近は .jpeg という拡張子はあまり使わないと思いますが。
    デジカメが普及するまでは .jpeg 拡張子の方が普通だったと思いますが、DCF 規格が .JPG にしたので、.jpg が主流になってしまいました。

  4. おっと~失礼しました。 操作ミスったかとおもって、何も考えずにつけてしまいました。 SQL 修正いたしました。

    ありがとうございます。 🙂

コメントを残す