Make WordPress Core

Ticket #51058: attachment_url_to_postid.patch

File attachment_url_to_postid.patch, 2.7 KB (added by jdorner, 4 years ago)

Patch to address making attachment_url_to_postid work for all attachment sizes and for permalinks and for "scaled" images

Line 
1
2function attachment_url_to_postid( $url ) {
3        global $wpdb;
4
5        $dir  = wp_get_upload_dir();
6        $path = $url;
7
8        $site_url   = parse_url( $dir['url'] );
9        $image_path = parse_url( $path );
10        $post_id = 0;
11
12        if ( $attachment_id_pos = strpos( $url, '?attachment_id=' ) ) {
13        // "plain" url (permalinks not enabled)
14                $starting_pos = $attachment_id_pos + 15; // 15 = length of "?attachment_id="
15                $post_id = substr( $url, $starting_pos );
16        } elseif ( $attachment_id = url_to_postid( $url ) ) {
17                // this is an attachment permalink
18                $post_id = $attachment_id;
19        } else {
20                // compensate for sizes
21        // reduce path to original filename
22                $path_parts = explode( '-', $image_path['path'] );
23                $filename = end( $path_parts );
24                $found = preg_match('/^[\d]+x[\d]+(\.[0-9a-zA-Z]{3,4})/', $filename, $matches );
25                if ( $found ) {
26                        // size found
27                        $meta_values[] = str_replace( '-' . $matches[0], $matches[1], $path );
28                        $meta_values[] = str_replace( '-' . $matches[0], '-scaled'. $matches[1], $path );
29                } else {
30            // no size found
31                        $meta_values[] = $path;
32                        $extension = '.'. pathinfo( $path, PATHINFO_EXTENSION );
33                        $meta_values[] = str_replace( $extension, '-scaled'. $extension, $path );
34                }
35
36                foreach( $meta_values as $key => $value ) {
37                        // Force the protocols to match if needed.
38                        if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) {
39                                $meta_values[ $key ] = str_replace( $image_path['scheme'], $site_url['scheme'], $meta_values[ $key ] );
40                        }
41            // remove baseurl from path
42                        if ( 0 === strpos( $meta_values[ $key ], $dir['baseurl'] . '/' ) ) {
43                                $meta_values[ $key ] = substr( $meta_values[ $key ], strlen( $dir['baseurl'] . '/' ) );
44                        }
45                }
46
47                $sql = 'SELECT `post_id`, `meta_value` FROM '. $wpdb->postmeta .' WHERE meta_key = "_wp_attached_file" AND ( `meta_value` = %s';
48                if( isset( $meta_values[1] ) ) {
49            // handle "-scaled" images
50                        $sql .= ' OR `meta_value` = %s';
51                }
52                $sql .= ')';
53                $sql = $wpdb->prepare( $sql, $meta_values );
54                $results = $wpdb->get_results( $sql );
55
56                if ( $results ) {
57                        // Use the first available result, but prefer a case-sensitive match, if exists.
58                        $post_id = reset( $results )->post_id;
59
60                        if ( count( $results ) > 1 ) {
61                                foreach ( $results as $result ) {
62                    if( in_array( $result->meta_value, $meta_values) ) {
63                                                $post_id = $result->post_id;
64                                                break;
65                                        }
66                                }
67                        }
68                }
69
70        }
71        /**
72         * Filters an attachment ID found by URL.
73         *
74         * @since 4.2.0
75         *
76         * @param int|null $post_id The post_id (if any) found by the function.
77         * @param string   $url     The URL being looked up.
78         */
79        return (int) apply_filters( 'attachment_url_to_postid', $post_id, $url );
80}