เปลี่ยน URL ให้เป็น Attachment / Post ID


32

มีวิธีใดบ้างที่ฉันสามารถใช้ URL ของรูปภาพและค้นหาสิ่งที่แนบหรือรหัสโพสต์ของรูปภาพนั้นในฐานข้อมูล

นี่คือสถานการณ์:

ฉันกำลังวนดูแท็ก 'img' ทั้งหมดที่ล้อมรอบด้วยแท็ก 'a' ในเนื้อหาโพสต์ของฉัน หากแอตทริบิวต์ src ของแท็ก 'img' ไม่ตรงกับแอตทริบิวต์ href ของแท็ก 'a' ด้านนอกดังนั้นฉันต้องการแทนที่แท็ก '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;
}

เห็นได้ชัดว่ามันไม่ถูกต้องเพราะ guid นั้นเป็นเรื่องที่ไม่ซ้ำกันทั่วโลก ฉันได้ (ก่อนหน้านี้ในสคริปต์เดียวกัน) อัปโหลดไฟล์ที่มีชื่อเดียวกัน (เพราะเหตุใดเพราะมันเป็นความละเอียดที่สูงขึ้นและฉันพยายามที่จะแทนที่รูปแบบความละเอียดต่ำของภาพเดียวกัน) และแม้ว่า wordpress จะบันทึกภาพด้วยชื่ออื่น ไดเรกทอรี guid ของถูกตั้งค่าให้เหมือนกัน (อาจเป็นข้อผิดพลาด)

มีเทคนิคอื่นที่ฉันสามารถใช้ได้หรือไม่?


คุณสามารถตั้งค่าตัวแปรคำขอได้ตาม URL ของคุณยกตัวอย่าง WP_Query และรับข้อมูลจากมัน
hakre

มันจะช่วยถ้าคุณสามารถอัปเดตคำถามของคุณและโพสต์ตัวอย่างของ HTML ที่มี URL ที่คุณต้องการแทนที่เพื่อให้เราสามารถพูดคุยกับพวกเขา
MikeSchinkel

ไมค์อยู่ตรงนั้น รูปภาพขนาดใหญ่กว่าที่คุณลิงก์ไปยังไซต์ภายนอกหรือไม่ ถ้าไม่เช่นนั้นคุณต้องเลือกขนาดเต็มเมื่อคุณเพิ่มรูปภาพในโพสต์ของคุณและคุณมีตัวเลือกที่จะไม่เชื่อมโยงที่ใดก็ได้หากไม่เหมาะสมอีกต่อไป
sanchothefat

คำตอบ:


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?
สตีเฟ่นแฮร์ริส

3
@StephenHarris เนื่องจาก URL สามารถชี้ไปที่ขนาดใดก็ได้ของรูปภาพซึ่งทั้งหมดมีชื่อไฟล์ที่แตกต่างกัน
Rarst

1
มันใช้งานได้ดี แต่มันก็คุ้มค่าที่จะสังเกตว่าตั้งแต่ WordPress 4 มีฟังก์ชั่นในตัวที่ทำตามที่กาเบรียลกล่าวไว้ในคำตอบอื่น มันทำงานในลักษณะเดียวกับที่ทำ
Chris Rae

2
@ChrisRae ถ้าคุณดูแหล่งที่มาฟังก์ชั่นหลักจะไม่ทำงานกับขนาดภาพเฉพาะในภาพหลัก
Rarst

ฉันคิดว่าฟังก์ชั่น WordPress ในตัวทำงานได้ดีขึ้น สิ่งนี้ไม่ทำงานในการผลิตของฉัน แต่ทำงานบน Staging (ซึ่งไม่มีใบรับรอง SSL) ฟังก์ชั่นในตัว (ตามที่อธิบายโดย Ego Ipse ด้านล่าง) ทำงานได้ในทั้งสองสภาพแวดล้อม
Syed Priom

15

ฟังก์ชั่นที่ซับซ้อนเหล่านั้นสามารถลดลงเป็นฟังก์ชั่นที่ง่ายอย่างหนึ่ง

attachment_url_to_postid ()

คุณจะต้องแยกวิเคราะห์ URL ของภาพเพื่อดึง ID ของไฟล์แนบ:

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

นั่นคือทั้งหมดที่คุณต้องการ


6
โดยเฉพาะอย่างยิ่งสิ่งนี้จะไม่ทำงานกับขนาดภาพรุ่นหลักจะค้นหาเฉพาะไฟล์ที่แนบ "หลัก"
Rarst

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

ตกลงฉันพบคำตอบที่ไม่มีใครในเน็ตฉันได้ค้นหาวันนี้ เก็บไว้ในเหมืองนี้จะทำงานเฉพาะในกรณีที่รูปแบบหรือปลั๊กอินของคุณใช้WP_Customize_Image_Control()ถ้าคุณกำลังใช้จะกลับ ID และไม่ได้ที่ urlWP_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.