จัดการปัญหาเกี่ยวกับการเปลี่ยนการปรับสเกลภาพ (การปัดเศษ) ใน 4.1 (WP Ticket # 18532)


17

ขณะนี้ฉันกำลังย้ายเนื้อหาของไซต์จากไซต์ก่อน 4.1 เก่าไปยังการตั้งค่าใหม่และตีปัญหาเกี่ยวกับปัญหาข้อผิดพลาดในการปัดเศษ# 18532และการแก้ไขที่เกี่ยวข้อง

เพื่อสรุปสิ่งนี้คงเป็นพฤติกรรมที่ไม่เหมาะสมรอบด้านของ WordPress:

ลองนึกภาพเราอัปโหลดภาพที่มี 693x173 และขยายเป็นความกว้าง 300:

  • ก่อน 4.1: 300x74
  • โพสต์ 4.1: 300x75

ปัญหา

โดยทั่วไปจะไม่ทำให้เกิดปัญหาใด ๆ เนื่องจากไฟล์ที่มีอยู่และ<img>ไม่ได้สัมผัส

แต่เมื่อคุณ regenerating นิ้วหัวแม่มือหรือสิ่งที่แนบนำเข้าจากไฟล์ WXR ที่พวกเขาได้รับการสร้างขึ้นแตกต่างกันในระบบแฟ้มทิ้ง<img>ในpost_contentที่ตายแล้ว

กำลังมองหาทางออก

ฉันคิดถึงวิธีแก้ปัญหาต่าง ๆ :

ย้อนกลับไปสู่ยุคสมัยที่เลวร้าย

เซ็ตการแก้ไข 30660แนะนำตัวกรองใหม่wp_constrain_dimensionsซึ่งสามารถใช้เพื่อเสียบการทำงานแบบเก่าจากก่อนหน้า 4.1 กลับมาอีกครั้งนี่เป็นการแก้ไขปัญหา แต่ฉันสงสัยว่าสิ่งนี้อาจทำให้เกิดปัญหาในภายหลังและโดยทั่วไปฉันต้องการแก้ไขดังนั้นแม้ว่างานนี้ฉันจะถือว่าไม่เหมาะ

เวลาที่พวกเขาอยู่ - ชางงี

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

แนวคิดปัจจุบันของฉันคือ:

  1. นำเข้าสร้างใหม่หรืออะไรก็ตามที่ทำให้เรามีไฟล์ใหม่และแท็กที่ใช้งานไม่ได้
  2. สร้างรายการ A จากไฟล์ที่ถูกปรับขนาดทั้งหมดในระบบไฟล์หรือรับข้อมูลนี้จากฐานข้อมูล
  3. แยกรายการนี้และสร้างรายการที่สอง B ที่มีชื่อไฟล์ทั้งหมดชดเชยโดยหนึ่งพิกเซลเช่นเดียวกับที่จะมองก่อน 4.1
  4. ค้นหาและแทนที่ฐานข้อมูลทั้งหมดเพื่อแทนที่สิ่งที่เกิดขึ้นทั้งหมดของ B ด้วยรายการที่เกี่ยวข้องใน A

ฉันไม่แน่ใจว่านี่เป็นวิธีที่ฉลาดและมีประสิทธิภาพที่สุดในการจัดการกับสถานการณ์นี้หรือไม่ นอกจากนี้ยังรู้สึกถึงแรงเดรัจฉานเกินไป ดังนั้นก่อนที่จะใช้มันฉันแค่ต้องการตรวจสอบกับภูมิปัญญาที่ไม่มีที่สิ้นสุดของฝูงชน WPSE;)

[แก้ไข] มีคำตอบอ่านck-macleodของ (ขอบคุณ!) ฉันคิดว่าการแก้ไขควรแก้ปัญหานี้ครั้งเดียวและทั้งหมดดังนั้นคุณไม่จำเป็นต้องให้ปัญหานี้อยู่ในหัวของคุณ [/ แก้ไข]

[edit2] ฉันเพิ่งพบตั๋วที่เกี่ยวข้องบน Trac การเพิ่มสำหรับการอ้างอิง [/ edit2]


ที่คุณได้error issue of #13852คุณหมายถึง#18532? :)
Aravona

2
โอ๊ะโอแก้ไขแล้ว :)
kraftner

คำตอบ:


4

นี่เป็นวิธีการอื่นที่ไม่ใช่คำตอบอื่น ๆที่ใช้งานได้เมื่อนำเข้าเนื้อหากับผู้นำเข้าและแก้ไข URL ทุกครั้ง อีกครั้ง: นี่ไม่ใช่การทดสอบการต่อสู้ แต่เป็นวิธีแก้ปัญหาที่ฉันตัดสินและใช้ได้

ฉันชอบสิ่งนี้เพราะมันแก้ปัญหาได้ทันทีและสำหรับทุกคนและถ้ามันใช้งานได้มันก็ใช้งานได้ ในขณะที่คุณไม่ทิ้งสิ่งที่แตกหักไว้ในฐานข้อมูลและแก้ไขมันบนจอแสดงผลคุณไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งที่จะแตกภายหลัง

/*
Plugin Name:  Bugfix Ticket 31581 for WP_Importer
Plugin URI:   /wordpress//a/206992/47733
Description:  Fixes image references after post WP 4.1 image scaling change in post content when using the WP_Importer  (see https://core.trac.wordpress.org/ticket/31581)
Version:      0.0.1
*/

class Bugfix31581WPImporter {

    protected $remaps;

    /**
     * Initialize class, mainly setting up hooks
     */
    public function init(){

        if (WP_IMPORTING === true){

            $this->remaps = array();

            //This hook is chosen because it is pretty close to where the actual attachment import is happening.
            //TODO: May be reconsidered.
            add_filter('wp_update_attachment_metadata', array($this, 'collectRemaps'), 10 , 2);

            add_action('import_end', array($this, 'remap'));
            add_action('import_end', array($this, 'importEnded'));
        }

    }

    /**
     * Cleans up hooks after the import has ended.
     */
    public function importEnded(){
        remove_filter('wp_update_attachment_metadata', array($this, 'collectRemaps'), 10);

        remove_action('import_end', array($this, 'remap'), 10);
        remove_action('import_end', array($this, 'importEnded'), 10);
    }

    /**
     * When an attachment is added compare the resulting sizes with the sizes from the legacy algorithm and setup remap.
     *
     * @param $data
     * @param $post_id
     *
     * @return mixed
     */
    public function collectRemaps($data, $post_id ){

        $intermediate_sizes = $this->getIntermediateSizes();

        if(empty($data) || !array_key_exists('sizes', $data)){
            return $data;
        }

        foreach($data['sizes'] as $key => $size){

            $size_new_algorithm = array($size['width'], $size['height']);

            $dest_w = $intermediate_sizes[$key]['width'];
            $dest_h = $intermediate_sizes[$key]['height'];
            $crop = $intermediate_sizes[$key]['crop'];

            add_filter('wp_constrain_dimensions', array($this, 'legacy_wp_constrain_dimensions'), 10, 5);

            $size_old_algorithm = image_resize_dimensions($data['width'], $data['height'], $dest_w, $dest_h, $crop);

            //Bail out in the rare case of `image_resize_dimensions` returning false
            if($size_old_algorithm===false){
                continue;
            }

            $size_old_algorithm = array($size_old_algorithm[4], $size_old_algorithm[5]);

            remove_filter('wp_constrain_dimensions', array($this, 'legacy_wp_constrain_dimensions'), 10);

            // Compare the current size with the calculation of the old algorithm...
            $diff = array_diff($size_new_algorithm, $size_old_algorithm);

            // ...to detect any mismatches
            if(!empty($diff)){

                $oldFilename = $this->getOldFilename($size['file'], $size_old_algorithm);

                // If getting the old filename didn't work for some reason (probably other filename-structure) bail out.
                if($oldFilename===false){
                    continue;
                }

                if(!array_key_exists($post_id, $this->remaps)){
                    $this->remaps[$post_id] = array();
                }

                $this->remaps[$post_id][$size['file']] = array(
                    'file' => $oldFilename,
                    'size' => $key
                );
            }

        }

        return $data;
    }

    /**
     * Get resize settings for all image sizes
     *
     * Taken from wp_generate_attachment_metadata() in includes/image.php
     *
     * @return array
     */
    public function getIntermediateSizes(){

        global $_wp_additional_image_sizes;

        $sizes = array();
        foreach ( get_intermediate_image_sizes() as $s ) {
            $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
            if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
                $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
            else
                $sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
            if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
                $sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
            else
                $sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
            if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
                $sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop']; // For theme-added sizes
            else
                $sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
        }

        return $sizes;
    }

    /**
     * Turn the new filename into the old filename reducing the height by one
     *
     * @param $newFilename
     * @param $size
     *
     * @return mixed
     */
    public function getOldFilename($newFilename, $size){

        $dimensions = array();

        $filetypes = $this->getAllowedImageExtentions();

        // TODO: This pattern can be different. See `image_make_intermediate_size` in image editor implementation.
        $matchFiles = '/([0-9]{1,5})x([0-9]{1,5}).(' . $filetypes . ')$/';

        // Extract the dimensions
        preg_match($matchFiles,$newFilename,$dimensions);

        // If the file URL doesn't allow guessing the dimensions bail out.
        if(empty($dimensions)){
            return $newFilename;
        }

        $newStub = $dimensions[1] . 'x' . $dimensions[2] . '.' . $dimensions[3];

        $oldStub = $size[0] . 'x' . $size[1] . '.' . $dimensions[3];

        $oldFilename = str_replace($newStub,$oldStub,$newFilename);

        return $oldFilename;
    }

    /**
     * Extract all file extensions that match an image/* mime type
     *
     * @return string
     */
    protected function getAllowedImageExtentions(){
        $allowed_filetypes = get_allowed_mime_types();

        $allowed_images = array();

        foreach($allowed_filetypes as $extensions => $mimetype){
            if( substr($mimetype,0,6) == 'image/' ){
                $allowed_images[] = $extensions;
            }
        }

        return implode('|',$allowed_images);
    }


    /**
     * This is the heart of this class. Based on the collected remaps from earlier it does a S&R on the DB.
     */
    public function remap(){

        global $wpdb;

        foreach($this->remaps as $attachment_id => $replaces){

            foreach($replaces as $new_url => $old_data){

                $to_url = wp_get_attachment_image_src($attachment_id,$old_data['size']);
                $to_url = $to_url[0];

                $from_url = str_replace($new_url, $old_data['file'], $to_url);

                // remap urls in post_content
                $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) );

                //TODO: This is disabled as enclosures can't be images, right?
                // remap enclosure urls
                //$result = $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url) );

            }

        }

    }

    /**
     * This is a copy of the legacy pre 4.1 wp_constrain_dimensions()
     *
     * @param $dimensions
     * @param $current_width
     * @param $current_height
     * @param $max_width
     * @param $max_height
     *
     * @return array
     */
    public function legacy_wp_constrain_dimensions($dimensions, $current_width, $current_height, $max_width, $max_height){
        if ( !$max_width and !$max_height )
            return array( $current_width, $current_height );

        $width_ratio = $height_ratio = 1.0;
        $did_width = $did_height = false;

        if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
            $width_ratio = $max_width / $current_width;
            $did_width = true;
        }

        if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
            $height_ratio = $max_height / $current_height;
            $did_height = true;
        }

        // Calculate the larger/smaller ratios
        $smaller_ratio = min( $width_ratio, $height_ratio );
        $larger_ratio  = max( $width_ratio, $height_ratio );

        if ( intval( $current_width * $larger_ratio ) > $max_width || intval( $current_height * $larger_ratio ) > $max_height )
            // The larger ratio is too big. It would result in an overflow.
            $ratio = $smaller_ratio;
        else
            // The larger ratio fits, and is likely to be a more "snug" fit.
            $ratio = $larger_ratio;

        // Very small dimensions may result in 0, 1 should be the minimum.
        $w = max ( 1, intval( $current_width  * $ratio ) );
        $h = max ( 1, intval( $current_height * $ratio ) );

        // Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
        // We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
        // Thus we look for dimensions that are one pixel shy of the max value and bump them up
        if ( $did_width && $w == $max_width - 1 )
            $w = $max_width; // Round it up
        if ( $did_height && $h == $max_height - 1 )
            $h = $max_height; // Round it up

        return array( $w, $h );
    }

}

add_filter('import_start',array(new Bugfix31581WPImporter(),'init'));

ใช้งานได้ดี +1
gmazzap

1

การแก้ปัญหาในระดับโลกและสมบูรณ์แบบสำหรับไฟล์รูปภาพทั้งหมด (และลิงก์) ในเว็บไซต์ขนาดใหญ่ - เนื่องจากมีความเป็นไปได้เช่นบุคคลอาจเปลี่ยนชื่อไฟล์ภาพเป็นครั้งคราวเพื่อเลียนแบบสไตล์ WP - และรูปแบบแปลก ๆ อื่น ๆ ด้วยตนเอง การค้นหาฐานข้อมูลและการดำเนินการแทนที่จะดำเนินไปด้วยความยุ่งยาก (และความเสี่ยง!)

คุณสามารถจัดการข้อผิดพลาดส่วนใหญ่ได้หรือไม่ - ภาพที่เสียและลิงค์ภาพที่เสียหายฉันเข้าใจ - และบรรลุผลลัพธ์ที่ต้องการหรือโทรสารที่เหมาะสมด้วยวิธีการต่อไปนี้หรือไม่?

  1. ระบุวันที่ก่อนที่ภาพจะถูกปรับขนาดทั้งหมดซึ่งปรับขนาดด้วยวิธี "intval" แบบเก่าแทนที่จะเป็นวิธี "แบบกลม" แบบใหม่ (สามารถตัดการแตกต่างกันได้ แต่วันที่ดูง่ายที่สุด)

  2. สำหรับโพสต์ทั้งหมดที่เผยแพร่ <= วันที่ตัดให้เรียกใช้ preg_replace บน the_content () ณ เวลาที่โหลด / แสดงภาพจับไฟล์ภาพทั้งหมดด้วยรูปแบบปัญหาหรือรูปแบบและแทนที่ด้วยรูปแบบที่ต้องการ ฐานข้อมูลจะยังคงไม่เปลี่ยนแปลง แต่ผลลัพธ์จะปราศจากข้อผิดพลาดในกรณีส่วนใหญ่ ฉันไม่แน่ใจว่าโซลูชันจะต้องใช้ทั้งกับเนื้อหาโพสต์ในหน้า "เอกพจน์" และเพื่อเก็บถาวรหน้าและกระบวนการอื่น ๆ ด้วยหรือไม่

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

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

หากคุณสามารถ จำกัด รูปแบบปัญหาให้แคบลงได้มากขึ้นและอินสแตนซ์ที่จำเป็นต้องแก้ไขผลลัพธ์ฉันจะเห็นการเสียบปลั๊กในรูปแบบของฉัน - ซึ่งไม่ซับซ้อนมากและ RegExer ที่ดีกว่าฉัน แม้จะเป็นเรื่องง่าย ในทางกลับกันฉันไม่ต้องการเสียเวลากับตัวเองหากวิธีการนี้ไม่สามารถตอบปัญหาให้คุณได้


ขอบคุณสำหรับเวลาของคุณ! แค่ความคิดบางอย่าง: ฉันคิดว่ามีข้อมูลที่ไม่ถูกต้องในฐานข้อมูลและเพียงแค่การติดตั้งลิงบนจอแสดงผลไม่ใช่วิธีที่สะอาดและยั่งยืน มันอาจทำลายได้ตลอดเวลาและเป็นอันตรายต่อประสิทธิภาพการทำงานของแต่ละมุมมอง นอกจากนี้ยังอาจมีผลข้างเคียงที่คาดเดาไม่ได้เช่นสำหรับปลั๊กอินอื่น ๆ ที่แยกวิเคราะห์หรือแก้ไขเนื้อหาด้วยวิธีอื่น ขึ้นอยู่กับว่ามันจะทำอย่างไรภาพก็ยังคงอยู่ในแบ็กเอนด์ ในกรณีนั้นฉันคิดว่าเพียงรีเซ็ตการปรับสเกลผ่านwp_constrain_dimensionsตามที่กล่าวไว้ในคำถามในขณะที่การนำเข้าและการละเว้นจากการสร้างนิ้วโป้งขึ้นใหม่จะสะอาดขึ้น
Kraftner

คุณค่อนข้างยินดีต้อนรับ สิ่งนั้นคือข้อมูลใน DB ไม่ใช่ข้อมูลที่ผิด แต่ไม่ใช่ข้อมูลที่คุณต้องการอีกต่อไปภายใต้ระบอบการปกครองใหม่ ฉันคิดว่ามันน่าจะมีน้อยที่สุดโดยเฉพาะในทางทฤษฎีกับโพสต์ก่อนวันที่ X โดยทั่วไปอาจไม่มีทางออกที่ดีที่สุดขนาดเดียวเหมาะกับทุกคน: ฉันคิดว่าสิ่งที่ดี วิธีแก้ปัญหาที่เพียงพออาจแตกต่างกันไปตามลักษณะของไซต์แอปพลิเคชันและนิสัยในการจัดการรูปภาพที่ผ่านมาขนาดของฐานข้อมูลข้อ จำกัด ในทางปฏิบัติและเวลาและอื่น ๆ
CK MacLeod

คุณอาจถูกต้องว่าจะไม่มีวิธีแก้ปัญหาที่เหมาะกับทุกขนาด ขณะนี้ฉันกำลังสำรวจวิธีการต่าง ๆ ในการจัดการกับสิ่งเหล่านี้ซึ่งเป็นวิธีการแสดงผลที่คล้ายกับของคุณและวิธีการนำเข้าที่ฉันต้องการเพราะมันสามารถแก้ไขปัญหานี้ได้ในทุกครั้ง เราจะดูว่าสิ่งนี้นำไปสู่อะไร :)
kraftner

1

โอเคนี่เป็นวิธีการพื้นฐานในการแทนที่ภาพที่เสียหายได้ทันที ระวังให้ดีว่านี่เป็นข้อพิสูจน์ของแนวคิดมากกว่าโซลูชันทดสอบการต่อสู้ มันแค่ขอเกี่ยวกับthe_contentตัวกรองซึ่งอาจมีผลข้างเคียงที่ไม่พึงประสงค์ในบางสถานการณ์ จัดการด้วยความระมัดระวัง. :)

แม้ว่าจะระบุไว้ในรหัสด้วย แต่ฉันก็ต้องการให้เครดิต@Rarstสำหรับคำตอบนี้ที่ใช้ในรหัสของฉัน

/*
Plugin Name:  Bugfix 31581 Live
Plugin URI:   /wordpress//a/206986/47733
Description:  Fixes image references in post content after post 4.1 image scaling change (see https://core.trac.wordpress.org/ticket/31581)
Version:      0.0.1
*/

class Bugfix31581Live {

    protected $matchURLs;
    protected $matchFiles;

    protected $remaps;

    public function init(){

        $filetypes = $this->get_allowed_image_extentions();

        $baseurl = wp_upload_dir();
        $baseurl = preg_quote($baseurl['baseurl'], '/');

        $this->matchURLs = '/' . $baseurl . '\/.??([a-zA-Z0-9_-]*?\.(?:' . $filetypes . '))/';

        //TODO: This pattern can be different. See `image_make_intermediate_size` in image editor implementation
        $this->matchFiles = '/([0-9]{1,4})x([0-9]{1,4}).(' . $filetypes . ')$/';

        add_filter('the_content', array($this, 'update_urls') );
    }

    public function update_urls($content){

        $urls = array();

        preg_match_all($this->matchURLs,$content,$urls);

        // Bail out early if we don't have any match.
        if($urls === false || empty($urls[0])){
            return $content;
        }

        // Loop through all matches
        foreach($urls[0] as $url){

            // Try to resolve this URL to an attachment ID
            $id = $this->get_attachment_id($url);

            // If not  let's see if this might be a URL that has been broken by our beloved Changeset 30660
            if( $id === false ){

                $dimensions = array();

                // Extract the dimensions
                preg_match($this->matchFiles,$url,$dimensions);

                // If the file URL doesn't allow guessing the dimensions bail out.
                if(empty($dimensions)){
                    continue;
                }

                // Old filename
                $old = $dimensions[1] . 'x' . $dimensions[2] . '.' . $dimensions[3];

                // New filename (not sure if this exists yet)
                $new = $dimensions[1] . 'x' . ($dimensions[2]+1) . '.' . $dimensions[3];

                // Build the new URL (not sure if this exists yet)
                $new_url = str_replace($old,$new,$url);

                // Try to get the attachment with the new url
                $id = $this->get_attachment_id($new_url);

                // Bad luck. This also doesn't exist.
                if( $id === false ) {
                    continue;
                }

                // Just to be sure everything is in sync we get the URL built from id and size.
                $db_url = wp_get_attachment_image_src($id,array($dimensions[1], $dimensions[2]+1));

                // Check if the URL we created and the one wp_get_attachment_image_src builds are the same.
                if($new_url === $db_url[0]){

                    // Awesome let's replace the broken URL.
                    $content = str_replace($url,$new_url,$content);
                }

            }

        }

        return $content;
    }

    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   /wordpress//a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    protected 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(
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

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

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

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                $tmp = wp_get_attachment_image_src( $id, 'full' );

                // first entry of returned array is the URL
                if ( $url === array_shift( $tmp ) )
                    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 ) {

                $tmp = wp_get_attachment_image_src( $id, $size );

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

        return false;
    }

    protected function get_allowed_image_extentions(){
        $allowed_filetypes = get_allowed_mime_types();

        $allowed_images = array();

        foreach($allowed_filetypes as $extensions => $mimetype){
            if( substr($mimetype,0,6) == 'image/' ){
                $allowed_images[] = $extensions;
            }
        }

        return implode('|',$allowed_images);
    }

}

add_filter('init',array(new Bugfix31581Live(),'init'));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.