URLを添付ファイル/投稿IDに変換する


32

画像のURLを取得して、データベース内でその画像の添付ファイルまたは投稿IDを見つける方法はありますか?

状況は次のとおりです。

私は、投稿コンテンツで「a」タグに囲まれているすべての「img」タグを巡回しています。「img」タグのsrc属性が外側の「a」タグのhref属性と一致しない場合、「img」タグを置き換えたいと思います。これを行う際に、削除する「img」がギャラリーにある場合、その投稿を削除してから、代わりの「img」をその場所に配置します。私はこのような関数を使用してみました:

function find_image_post_id($url) {
  global $wpdb;
  $postid = $wpdb->get_var($wpdb->prepare("SELECT DISTINCT ID FROM $wpdb->posts WHERE guid='$url'"));
  if ($postid) {
    return $postid;
  }
  return false;
}

皮肉なことに皮肉なことにグローバルに一意ではないため、これは明らかに正しくありません。私は(以前の同じスクリプトで)同じ名前のファイルをアップロードしていました(なぜですか?高解像度で同じ画像の低解像度バージョンを置き換えようとしているためです)が、wordpressは別の名前で画像を保存しますがディレクトリ、GUIDは同じに設定されました。(おそらくバグ)。

私が使用できる別のテクニックはありますか?


URLに応じてリクエスト変数を設定し、WP_Queryをインスタンス化し、そこから情報を取得できます。
-hakre

質問を更新し、置換したいURLを含むHTMLの例を投稿して、議論することができれば助かります。
MikeSchinkel

マイクはすぐそこにいます。外部サイトでリンクしている大きな画像はありますか?そうでない場合は、投稿に画像を追加するときにフルサイズを選択する必要があり、意味をなさない場合はどこにもリンクしないオプションがあります。
サンチョテファット

回答:


30

画像の重いプラグイン用に開発された大幅に改善された機能:

if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'key'     => '_wp_attached_file',
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}

1
_wp_attached_fileとの両方をクエリする理由を説明できます_wp_attachment_metadataか?
スティーブンハリス14

3
@StephenHarrisは、URLが任意の画像サイズを指すことができ、それらはすべて異なるファイル名を持っているため
Rarst 14

1
これはうまく機能しますが、WordPress 4以降、Gabrielが別の回答で述べたように、それを行うための組み込み関数があります。これは、これとまったく同じように機能します。
クリス・レイ

2
@ChrisRaeソースを見ると、コア関数は画像サイズでは機能せず、メイン画像でのみ機能します。
ラスト

組み込みのWordPress機能がより良く機能すると思います。これは私の実稼働環境では機能しませんでしたが、ステージング(SSL証明書がない)では機能しました。組み込み関数(以下のEgo Ipseで指摘)は、両方の環境で機能します。
Syed Priom

15

これらすべての複雑な関数は、1つの単純な関数にまとめることができます。

attachment_url_to_postid()

画像URLを解析するだけで、添付ファイルIDを取得できます。

$attachment_id = attachment_url_to_postid( $image_url );
echo $attachment_id;

必要なのはそれだけです。


6
特に、これはイメージサイズでは機能しません。コアバージョンは「メイン」添付ファイルのみを検索します。
ラスト

3

Rarstのコードを変更して、フルパスではなくファイル名のみを一致させることができました。これは、画像が存在しない場合にサイドロードしようとする場合に役立ちます。現在、これはファイル名が一意である場合にのみ機能しますが、同じファイル名を持つ画像を支援するために後でハッシュチェックを追加します。

function get_attachment_id( $url, $ignore_path = false ) {

if ( ! $ignore_path ) {

    $dir = wp_upload_dir();
    $dir = trailingslashit($dir['baseurl']);

    if( false === strpos( $url, $dir ) )
        return false;
}

$file = basename($url);

$query = array(
    'post_type' => 'attachment',
    'fields' => 'ids',
    'meta_query' => array(
        array(
            'key'     => '_wp_attached_file',
            'value'   => $file,
            'compare' => 'LIKE',
        )
    )
);

$ids = get_posts( $query );

foreach( $ids as $id ) {
    $match = array_shift( wp_get_attachment_image_src($id, 'full') );
    if( $url == $match || ( $ignore_path && strstr( $match, $file ) ) )
        return $id;
}

$query['meta_query'][0]['key'] = '_wp_attachment_metadata';
$ids = get_posts( $query );

foreach( $ids as $id ) {

    $meta = wp_get_attachment_metadata($id);

    foreach( $meta['sizes'] as $size => $values ) {
        if( $values['file'] == $file && ( $ignore_path || $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) )
            return $id;
    }
}

return false;
}

3

[OK]を私は私が今何日も探していたネット上に誰もいないという答えを見つけました。あなたのテーマやプラグインを使用している場合にのみ動作鉱山でこれを維持しWP_Customize_Image_Control()、使用している場合はIDとないURLを返します。WP_Customize_Media_Control()get_theme_mod()

私のソリューションでは、新しいバージョンを使用していました WP_Customize_Image_Control()

フォーラムの多くの投稿には、get_attachment_id()もう機能しないものがあります。私は使ったattachment_url_to_postid()

ここに私がそれをどうやってできたかがあります。これが誰かを助けることを願っています

// This is getting the image / url
$feature1 = get_theme_mod('feature_image_1');

// This is getting the post id
$feature1_id = attachment_url_to_postid($feature1);

// This is getting the alt text from the image that is set in the media area
$image1_alt = get_post_meta( $feature1_id, '_wp_attachment_image_alt', true );

マークアップ

<a href="<?php echo $feature1_url; ?>"><img class="img-responsive center-block" src="<?php echo $feature1; ?>" alt="<?php echo $image1_alt; ?>"></a>

0

代替ソリューションは次のとおりです。

$image_url = get_field('main_image'); // in case of custom field usage
$image_id = attachment_url_to_postid($image_url);

// retrieve the thumbnail size of our image
$image_thumb = wp_get_attachment_image_src($image_id, 'thumbnail');

WP 4.0以降、彼らはattachment_url_to_postid()あなたのものと同様に動作する関数を導入しましたfind_image_post_id()

参照用にこのURLを確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.