WordPress.org

Make WordPress Core

Ticket #33768: include-image-metadata-wp-prepare-imagefor-js.php

File include-image-metadata-wp-prepare-imagefor-js.php, 7.5 KB (added by SteveHoneyNZ, 4 years ago)
Line 
1<?php
2/**
3 * Prepares an attachment post object for JS, where it is expected
4 * to be JSON-encoded and fit into an Attachment model.
5 *
6 * @since 3.5.0
7 *
8 * @param mixed $attachment Attachment ID or object.
9 * @return array|void Array of attachment details.
10 */
11function wp_prepare_attachment_for_js( $attachment ) {
12        if ( ! $attachment = get_post( $attachment ) )
13                return;
14
15        if ( 'attachment' != $attachment->post_type )
16                return;
17
18        $meta = wp_get_attachment_metadata( $attachment->ID );
19        if ( false !== strpos( $attachment->post_mime_type, '/' ) )
20                list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
21        else
22                list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
23
24        $attachment_url = wp_get_attachment_url( $attachment->ID );
25
26        $response = array(
27                'id'          => $attachment->ID,
28                'title'       => $attachment->post_title,
29                'filename'    => wp_basename( get_attached_file( $attachment->ID ) ),
30                'url'         => $attachment_url,
31                'link'        => get_attachment_link( $attachment->ID ),
32                'alt'         => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
33                'author'      => $attachment->post_author,
34                'description' => $attachment->post_content,
35                'caption'     => $attachment->post_excerpt,
36                'name'        => $attachment->post_name,
37                'status'      => $attachment->post_status,
38                'uploadedTo'  => $attachment->post_parent,
39                'date'        => strtotime( $attachment->post_date_gmt ) * 1000,
40                'modified'    => strtotime( $attachment->post_modified_gmt ) * 1000,
41                'menuOrder'   => $attachment->menu_order,
42                'mime'        => $attachment->post_mime_type,
43                'type'        => $type,
44                'subtype'     => $subtype,
45                'icon'        => wp_mime_type_icon( $attachment->ID ),
46                'dateFormatted' => mysql2date( get_option('date_format'), $attachment->post_date ),
47                'nonces'      => array(
48                        'update' => false,
49                        'delete' => false,
50                        'edit'   => false
51                ),
52                'editLink'   => false,
53                'meta'       => false,
54        );
55
56        $author = new WP_User( $attachment->post_author );
57        $response['authorName'] = $author->display_name;
58
59        if ( $attachment->post_parent ) {
60                $post_parent = get_post( $attachment->post_parent );
61        } else {
62                $post_parent = false;
63        }
64
65        if ( $post_parent ) {
66                $parent_type = get_post_type_object( $post_parent->post_type );
67                if ( $parent_type && $parent_type->show_ui && current_user_can( 'edit_post', $attachment->post_parent ) ) {
68                        $response['uploadedToLink'] = get_edit_post_link( $attachment->post_parent, 'raw' );
69                }
70                $response['uploadedToTitle'] = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' );
71        }
72
73        $attached_file = get_attached_file( $attachment->ID );
74        if ( file_exists( $attached_file ) ) {
75                $bytes = filesize( $attached_file );
76                $response['filesizeInBytes'] = $bytes;
77                $response['filesizeHumanReadable'] = size_format( $bytes );
78        }
79
80        if ( current_user_can( 'edit_post', $attachment->ID ) ) {
81                $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID );
82                $response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID );
83                $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' );
84        }
85
86        if ( current_user_can( 'delete_post', $attachment->ID ) )
87                $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID );
88
89        if ( $meta && 'image' === $type ) {
90                $sizes = array();
91
92                /** This filter is documented in wp-admin/includes/media.php */
93                $possible_sizes = apply_filters( 'image_size_names_choose', array(
94                        'thumbnail' => __('Thumbnail'),
95                        'medium'    => __('Medium'),
96                        'large'     => __('Large'),
97                        'full'      => __('Full Size'),
98                ) );
99                unset( $possible_sizes['full'] );
100
101                // Loop through all potential sizes that may be chosen. Try to do this with some efficiency.
102                // First: run the image_downsize filter. If it returns something, we can use its data.
103                // If the filter does not return something, then image_downsize() is just an expensive
104                // way to check the image metadata, which we do second.
105                foreach ( $possible_sizes as $size => $label ) {
106
107                        /** This filter is documented in wp-includes/media.php */
108                        if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) {
109                                if ( ! $downsize[3] )
110                                        continue;
111                                $sizes[ $size ] = array(
112                                        'height'      => $downsize[2],
113                                        'width'       => $downsize[1],
114                                        'url'         => $downsize[0],
115                                        'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape',
116                                );
117                        } elseif ( isset( $meta['sizes'][ $size ] ) ) {
118                                if ( ! isset( $base_url ) )
119                                        $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
120
121                                // Nothing from the filter, so consult image metadata if we have it.
122                                $size_meta = $meta['sizes'][ $size ];
123
124                                // We have the actual image size, but might need to further constrain it if content_width is narrower.
125                                // Thumbnail, medium, and full sizes are also checked against the site's height/width options.
126                                list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' );
127
128                                $sizes[ $size ] = array(
129                                        'height'      => $height,
130                                        'width'       => $width,
131                                        'url'         => $base_url . $size_meta['file'],
132                                        'orientation' => $height > $width ? 'portrait' : 'landscape',
133                                );
134                        }
135                }
136
137                $sizes['full'] = array( 'url' => $attachment_url );
138
139                if ( isset( $meta['height'], $meta['width'] ) ) {
140                        $sizes['full']['height'] = $meta['height'];
141                        $sizes['full']['width'] = $meta['width'];
142                        $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
143                }
144                       
145                if ( isset( $meta['image_meta'] ) ) {
146                        $response['meta'] = $meta['image_meta'];
147                }
148
149                $response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] );
150               
151               
152        } elseif ( $meta && 'video' === $type ) {
153                if ( isset( $meta['width'] ) )
154                        $response['width'] = (int) $meta['width'];
155                if ( isset( $meta['height'] ) )
156                        $response['height'] = (int) $meta['height'];
157        }
158
159        if ( $meta && ( 'audio' === $type || 'video' === $type ) ) {
160                if ( isset( $meta['length_formatted'] ) )
161                        $response['fileLength'] = $meta['length_formatted'];
162
163                $response['meta'] = array();
164                foreach ( wp_get_attachment_id3_keys( $attachment, 'js' ) as $key => $label ) {
165                        $response['meta'][ $key ] = false;
166
167                        if ( ! empty( $meta[ $key ] ) ) {
168                                $response['meta'][ $key ] = $meta[ $key ];
169                        }
170                }
171
172                $id = get_post_thumbnail_id( $attachment->ID );
173                if ( ! empty( $id ) ) {
174                        list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' );
175                        $response['image'] = compact( 'src', 'width', 'height' );
176                        list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' );
177                        $response['thumb'] = compact( 'src', 'width', 'height' );
178                } else {
179                        $src = wp_mime_type_icon( $attachment->ID );
180                        $width = 48;
181                        $height = 64;
182                        $response['image'] = compact( 'src', 'width', 'height' );
183                        $response['thumb'] = compact( 'src', 'width', 'height' );
184                }
185        }
186
187        if ( function_exists('get_compat_media_markup') )
188                $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) );
189
190        /**
191         * Filter the attachment data prepared for JavaScript.
192         *
193         * @since 3.5.0
194         *
195         * @param array      $response   Array of prepared attachment data.
196         * @param int|object $attachment Attachment ID or object.
197         * @param array      $meta       Array of attachment meta data.
198         */
199        return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta );
200}