Ubah URL menjadi ID Lampiran / Pos

32

Apakah ada cara saya dapat mengambil URL dari suatu gambar dan menemukan lampiran atau id posting dari gambar itu dalam basis data?

Inilah situasinya:

Saya dalam satu lingkaran memeriksa semua tag 'img' yang dikelilingi oleh tag 'a' di konten posting saya. jika atribut src dari tag 'img' tidak cocok dengan atribut href dari tag 'a' luar, maka saya ingin mengganti tag 'img'. Dalam melakukan ini, jika 'img' yang akan dihapus ada di galeri, saya ingin menghapus posting itu, dan kemudian meletakkan 'img' pengganti saya di tempatnya. Saya mencoba menggunakan fungsi seperti ini:

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;
}

Ini tampaknya tidak benar karena secara ironis pedoman ini tidak unik secara global. Saya telah (sebelumnya dalam skrip yang sama) mengunggah file dengan nama yang sama (mengapa? Karena itu resolusi yang lebih tinggi dan saya mencoba untuk mengganti versi resolusi rendah dari gambar yang sama) dan walaupun wordpress akan menyimpan gambar dengan nama yang berbeda di direktori, pedoman itu ditetapkan sama. (mungkin bug).

Apakah ada teknik lain yang bisa saya gunakan?

Ankur
sumber
Anda dapat dengan mudah mengatur variabel permintaan sesuai dengan URL Anda, instantiate WP_Query dan dapatkan informasi darinya.
hakre
Ini akan membantu jika Anda dapat memperbarui pertanyaan Anda dan memposting beberapa contoh HTML Anda yang mencakup URL yang ingin Anda ganti sehingga kami dapat membahasnya.
MikeSchinkel
Mike ada di sana. Apakah gambar yang lebih besar Anda tautkan ke situs eksternal? Jika tidak maka Anda hanya perlu memilih ukuran penuh ketika Anda menambahkan gambar ke posting Anda dan Anda memiliki pilihan untuk tidak menautkannya di mana pun jika tidak masuk akal lagi.
sanchothefat

Jawaban:

30

Fungsi besar yang dikembangkan untuk plugin berat pada gambar:

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;
    }
}
Jarang
sumber
1
Bisakah Anda menjelaskan mengapa Anda menanyakan keduanya _wp_attached_filedan _wp_attachment_metadata?
Stephen Harris
3
@StephenHarris karena URL dapat menunjuk ke ukuran gambar mana saja, yang semuanya memiliki nama file yang berbeda
Rarst
1
Ini berfungsi dengan baik, tetapi perlu dicatat di sini bahwa, sejak WordPress 4, ada fungsi bawaan untuk melakukannya seperti yang disebutkan oleh Gabriel dalam jawaban lain. Cara kerjanya persis sama dengan yang ini.
Chris Rae
2
@ ChrisRae jika Anda melihat sumber fungsi inti tidak akan berfungsi pada ukuran gambar, hanya pada gambar utama.
Rarst
Saya pikir fungsi built in WordPress berfungsi lebih baik. Ini tidak berfungsi dalam produksi saya tetapi berhasil pada Pementasan (yang tidak memiliki sertifikat SSL). Fungsi bawaan (seperti yang ditunjukkan oleh Ego Ipse di bawah) berfungsi di kedua lingkungan.
Syed Priom
15

Semua fungsi kompleks tersebut dapat direduksi menjadi satu fungsi sederhana:

attachment_url_to_postid ()

Anda hanya perlu mengurai URL gambar untuk mengambil ID lampiran:

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

Itu yang kamu butuhkan.

Ego Ipse
sumber
6
Khususnya ini tidak akan bekerja pada ukuran gambar, versi inti hanya mencari file "utama" terlampir.
Rarst
3

Saya memodifikasi kode Rarst untuk memungkinkan Anda mencocokkan hanya nama file, bukan path lengkap. Ini bermanfaat jika Anda akan melakukan sideload gambar jika tidak ada. Saat ini ini hanya berfungsi jika nama file unik tetapi saya akan menambahkan pemeriksaan hash nanti untuk membantu dengan gambar yang memiliki nama file yang sama.

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;
}
Luke Gedeon
sumber
3

Ok saya menemukan jawaban bahwa tidak ada yang ada di internet saya sudah mencari hari sekarang. Perlu tambang ini hanya bekerja jika tema atau plugin menggunakan WP_Customize_Image_Control()jika Anda menggunakan WP_Customize_Media_Control()yang get_theme_mod()akan kembali ID dan tidak url.

Untuk solusi saya, saya menggunakan versi yang lebih baru WP_Customize_Image_Control()

Banyak posting di forum memiliki get_attachment_id()yang tidak berfungsi lagi. Saya menggunakanattachment_url_to_postid()

Inilah cara saya bisa melakukannya. Semoga ini bisa membantu seseorang di luar sana

// 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 );

Markup

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

Inilah solusi alternatif:

$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');

Sejak WP 4.0 mereka memperkenalkan fungsi attachment_url_to_postid()yang berperilaku mirip dengan Andafind_image_post_id()

Silakan periksa url ini untuk referensi Anda.

Lefan
sumber