PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / json-endpoints / class.wpcom-json-api-update-media-v1-1-endpoint.php
jetpack / json-endpoints Last commit date
jetpack 1 week ago class.wpcom-json-api-add-widget-endpoint.php 8 months ago class.wpcom-json-api-autosave-post-v1-1-endpoint.php 8 months ago class.wpcom-json-api-bulk-delete-post-endpoint.php 8 months ago class.wpcom-json-api-bulk-restore-post-endpoint.php 8 months ago class.wpcom-json-api-bulk-update-comments-endpoint.php 2 months ago class.wpcom-json-api-comment-endpoint.php 8 months ago class.wpcom-json-api-delete-media-endpoint.php 8 months ago class.wpcom-json-api-delete-media-v1-1-endpoint.php 8 months ago class.wpcom-json-api-edit-media-v1-2-endpoint.php 1 week ago class.wpcom-json-api-get-autosave-v1-1-endpoint.php 8 months ago class.wpcom-json-api-get-comment-counts-endpoint.php 8 months ago class.wpcom-json-api-get-comment-endpoint.php 8 months ago class.wpcom-json-api-get-comment-history-endpoint.php 8 months ago class.wpcom-json-api-get-comments-tree-endpoint.php 8 months ago class.wpcom-json-api-get-comments-tree-v1-1-endpoint.php 8 months ago class.wpcom-json-api-get-comments-tree-v1-2-endpoint.php 8 months ago class.wpcom-json-api-get-customcss.php 8 months ago class.wpcom-json-api-get-media-endpoint.php 8 months ago class.wpcom-json-api-get-media-v1-1-endpoint.php 8 months ago class.wpcom-json-api-get-media-v1-2-endpoint.php 8 months ago class.wpcom-json-api-get-post-counts-v1-1-endpoint.php 1 month ago class.wpcom-json-api-get-post-endpoint.php 8 months ago class.wpcom-json-api-get-post-v1-1-endpoint.php 1 month ago class.wpcom-json-api-get-site-endpoint.php 1 day ago class.wpcom-json-api-get-site-v1-2-endpoint.php 1 month ago class.wpcom-json-api-get-taxonomies-endpoint.php 4 months ago class.wpcom-json-api-get-taxonomy-endpoint.php 8 months ago class.wpcom-json-api-get-term-endpoint.php 8 months ago class.wpcom-json-api-list-comments-endpoint.php 1 month ago class.wpcom-json-api-list-dropdown-pages-endpoint.php 8 months ago class.wpcom-json-api-list-embeds-endpoint.php 8 months ago class.wpcom-json-api-list-media-endpoint.php 8 months ago class.wpcom-json-api-list-media-v1-1-endpoint.php 2 months ago class.wpcom-json-api-list-media-v1-2-endpoint.php 8 months ago class.wpcom-json-api-list-post-type-taxonomies-endpoint.php 8 months ago class.wpcom-json-api-list-post-types-endpoint.php 8 months ago class.wpcom-json-api-list-posts-endpoint.php 1 month ago class.wpcom-json-api-list-posts-v1-1-endpoint.php 1 month ago class.wpcom-json-api-list-posts-v1-2-endpoint.php 1 month ago class.wpcom-json-api-list-roles-endpoint.php 8 months ago class.wpcom-json-api-list-shortcodes-endpoint.php 8 months ago class.wpcom-json-api-list-terms-endpoint.php 8 months ago class.wpcom-json-api-list-users-endpoint.php 1 month ago class.wpcom-json-api-menus-v1-1-endpoint.php 2 months ago class.wpcom-json-api-post-endpoint.php 8 months ago class.wpcom-json-api-post-v1-1-endpoint.php 3 months ago class.wpcom-json-api-render-embed-endpoint.php 8 months ago class.wpcom-json-api-render-embed-reversal-endpoint.php 8 months ago class.wpcom-json-api-render-endpoint.php 3 months ago class.wpcom-json-api-render-shortcode-endpoint.php 8 months ago class.wpcom-json-api-sharing-buttons-endpoint.php 2 months ago class.wpcom-json-api-site-settings-endpoint.php 2 weeks ago class.wpcom-json-api-site-settings-v1-2-endpoint.php 8 months ago class.wpcom-json-api-site-settings-v1-3-endpoint.php 8 months ago class.wpcom-json-api-site-settings-v1-4-endpoint.php 1 month ago class.wpcom-json-api-site-user-endpoint.php 8 months ago class.wpcom-json-api-taxonomy-endpoint.php 8 months ago class.wpcom-json-api-update-comment-endpoint.php 7 months ago class.wpcom-json-api-update-customcss.php 8 months ago class.wpcom-json-api-update-media-endpoint.php 1 day ago class.wpcom-json-api-update-media-v1-1-endpoint.php 1 day ago class.wpcom-json-api-update-post-endpoint.php 2 months ago class.wpcom-json-api-update-post-v1-1-endpoint.php 2 months ago class.wpcom-json-api-update-post-v1-2-endpoint.php 2 months ago class.wpcom-json-api-update-site-homepage-endpoint.php 8 months ago class.wpcom-json-api-update-site-logo-endpoint.php 8 months ago class.wpcom-json-api-update-taxonomy-endpoint.php 8 months ago class.wpcom-json-api-update-term-endpoint.php 8 months ago class.wpcom-json-api-update-user-endpoint.php 8 months ago class.wpcom-json-api-upload-media-endpoint.php 8 months ago class.wpcom-json-api-upload-media-v1-1-endpoint.php 8 months ago
class.wpcom-json-api-update-media-v1-1-endpoint.php
250 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Update media item info v1.1 endpoint.
4 *
5 * Endpoint: v1.1/sites/%s/media/%d
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit( 0 );
10 }
11
12 new WPCOM_JSON_API_Update_Media_v1_1_Endpoint(
13 array(
14 'description' => 'Edit basic information about a media item.',
15 'group' => 'media',
16 'stat' => 'media:1:POST',
17 'min_version' => '1.1',
18 'max_version' => '1.1',
19 'method' => 'POST',
20 'path' => '/sites/%s/media/%d',
21 'path_labels' => array(
22 '$site' => '(int|string) Site ID or domain',
23 '$media_ID' => '(int) The ID of the media item',
24 ),
25
26 'request_format' => array(
27 'parent_id' => '(int) ID of the post this media is attached to',
28 'title' => '(string) The file name.',
29 'caption' => '(string) File caption.',
30 'description' => '(HTML) Description of the file.',
31 'alt' => '(string) Alternative text for image files.',
32 'rating' => '(string) Video only. Video rating.',
33 'display_embed' => '(string) Video only. Whether to share or not the video.',
34 'allow_download' => '(string) Video only. Whether the video can be downloaded or not.',
35 'privacy_setting' => '(int) Video only. The privacy level for the video.',
36 'artist' => '(string) Audio Only. Artist metadata for the audio track.',
37 'album' => '(string) Audio Only. Album metadata for the audio track.',
38 ),
39
40 'response_format' => array(
41 'ID' => '(int) The ID of the media item',
42 'date' => '(ISO 8601 datetime) The date the media was uploaded',
43 'post_ID' => '(int) ID of the post this media is attached to',
44 'author_ID' => '(int) ID of the user who uploaded the media',
45 'URL' => '(string) URL to the file',
46 'guid' => '(string) Unique identifier',
47 'file' => '(string) File name',
48 'extension' => '(string) File extension',
49 'mime_type' => '(string) File mime type',
50 'title' => '(string) File name',
51 'caption' => '(string) User provided caption of the file',
52 'description' => '(string) Description of the file',
53 'alt' => '(string) Alternative text for image files.',
54 'thumbnails' => '(object) Media item thumbnail URL options',
55 'height' => '(int) (Image & video only) Height of the media item',
56 'width' => '(int) (Image & video only) Width of the media item',
57 'length' => '(int) (Video & audio only) Duration of the media item, in seconds',
58 'exif' => '(array) (Image & audio only) Exif (meta) information about the media item',
59 'rating' => '(string) (Video only) VideoPress rating of the video',
60 'display_embed' => '(string) Video only. Whether to share or not the video.',
61 'allow_download' => '(string) Video only. Whether the video can be downloaded or not.',
62 'privacy_setting' => '(int) Video only. The privacy level for the video.',
63 'videopress_guid' => '(string) (Video only) VideoPress GUID of the video when uploaded on a blog with VideoPress',
64 'videopress_processing_done' => '(bool) (Video only) If the video is uploaded on a blog with VideoPress, this will return the status of processing on the video.',
65 ),
66
67 'example_request' => 'https://public-api.wordpress.com/rest/v1.1/sites/82974409/media/446',
68 'example_request_data' => array(
69 'headers' => array(
70 'authorization' => 'Bearer YOUR_API_TOKEN',
71 ),
72 'body' => array(
73 'title' => 'Updated Title',
74 ),
75 ),
76 )
77 );
78
79 // phpcs:disable PEAR.NamingConventions.ValidClassName.Invalid
80 /**
81 * Update media item info v1.1 class.
82 *
83 * @phan-constructor-used-for-side-effects
84 */
85 class WPCOM_JSON_API_Update_Media_v1_1_Endpoint extends WPCOM_JSON_API_Endpoint {
86 /**
87 * Whether the current user may edit the given media item.
88 *
89 * `upload_files` is a primitive capability and ignores any object passed to it,
90 * so it only tells us the caller may upload something, never that they may edit
91 * this particular item. A missing item is passed through so the caller receives
92 * the endpoint's own 404 rather than a 403. A userless request gets no exemption:
93 * `edit_post` fails closed for user 0 like any other caller.
94 *
95 * Non-attachments are refused outright. `get_post()` resolves any post type, so
96 * without this test a media endpoint edits ordinary posts, pages and revisions.
97 * The post-type test must stay below the missing-post passthrough: that branch
98 * returns true, so testing there would skip `edit_post` for ordinary posts.
99 *
100 * A non-attachment yields 403, not the 404 a missing item gets. This is a boolean
101 * gate, and `get_media_item*()` resolves any post type, so a passthrough would
102 * return 200 rather than 404. Revisit if clients conflate it with an auth failure.
103 *
104 * Do not move this into a trait: this file instantiates the endpoint above the
105 * class declaration, and `use Trait;` disables PHP early binding, which makes the
106 * file fatal with "Class not found".
107 *
108 * @param int $media_id Media post ID.
109 * @return bool
110 */
111 protected function current_user_can_edit_media_item( $media_id ) {
112 if ( ! current_user_can( 'upload_files' ) ) {
113 return false;
114 }
115
116 $post = get_post( $media_id );
117
118 if ( ! $post ) {
119 return true;
120 }
121
122 if ( 'attachment' !== $post->post_type ) {
123 return false;
124 }
125
126 return current_user_can( 'edit_post', $media_id );
127 }
128
129 /**
130 * Update media item info API v1.1 callback.
131 *
132 * @param string $path API path.
133 * @param int $blog_id Blog ID.
134 * @param int $media_id Media ID.
135 *
136 * @return object|WP_Error
137 */
138 public function callback( $path = '', $blog_id = 0, $media_id = 0 ) {
139 $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
140 if ( is_wp_error( $blog_id ) ) {
141 return $blog_id;
142 }
143
144 if ( ! $this->current_user_can_edit_media_item( $media_id ) ) {
145 return new WP_Error( 'unauthorized', 'User cannot edit media', 403 );
146 }
147
148 $item = $this->get_media_item_v1_1( $media_id );
149
150 if ( is_wp_error( $item ) ) {
151 return new WP_Error( 'unknown_media', 'Unknown Media', 404 );
152 }
153
154 $input = $this->input( true );
155 $insert = array();
156
157 if ( isset( $input['title'] ) ) {
158 $insert['post_title'] = $input['title'];
159 }
160
161 if ( isset( $input['caption'] ) ) {
162 $insert['post_excerpt'] = $input['caption'];
163 }
164
165 if ( isset( $input['description'] ) ) {
166 $insert['post_content'] = $input['description'];
167 }
168
169 if ( isset( $input['parent_id'] ) ) {
170 $insert['post_parent'] = $input['parent_id'];
171 }
172
173 if ( isset( $input['alt'] ) ) {
174 $alt = wp_strip_all_tags( $input['alt'], true );
175 update_post_meta( $media_id, '_wp_attachment_image_alt', $alt );
176 }
177
178 // audio only artist/album info.
179 if ( str_starts_with( $item->mime_type, 'audio/' ) ) {
180 $changed = false;
181 $id3data = wp_get_attachment_metadata( $media_id );
182
183 if ( ! is_array( $id3data ) ) {
184 $changed = true;
185 $id3data = array();
186 }
187
188 $id3_keys = array(
189 'artist' => __( 'Artist', 'jetpack' ),
190 'album' => __( 'Album', 'jetpack' ),
191 );
192
193 foreach ( $id3_keys as $key => $label ) {
194 if ( isset( $input[ $key ] ) ) {
195 $changed = true;
196 $id3data[ $key ] = wp_strip_all_tags( $input[ $key ], true );
197 }
198 }
199
200 if ( $changed ) {
201 wp_update_attachment_metadata( $media_id, $id3data );
202 }
203 }
204
205 // Pass the item to the handle_video_meta() that checks if it's a VideoPress item and saves it.
206 $result = $this->handle_video_meta( $media_id, $input, $item );
207
208 if ( is_wp_error( $result ) ) {
209 return $result;
210 }
211
212 $insert['ID'] = $media_id;
213 wp_update_post( (object) $insert );
214
215 $item = $this->get_media_item_v1_1( $media_id );
216 return $item;
217 }
218
219 /**
220 * Persist the VideoPress metadata if the given item argument is a VideoPress item.
221 *
222 * @param string $media_id The ID of the video.
223 * @param array $input The request input.
224 * @param stdClass $item The response item.
225 *
226 * @return bool|WP_Error
227 */
228 public function handle_video_meta( $media_id, $input, $item ) {
229 if ( ! class_exists( \Videopress_Attachment_Metadata::class ) ) {
230 return false;
231 }
232
233 if ( ! \Videopress_Attachment_Metadata::is_videopress_media( $item ) ) {
234 return false;
235 }
236
237 return \Videopress_Attachment_Metadata::persist_metadata(
238 $media_id,
239 $item->videopress_guid,
240 $input['title'] ?? null,
241 $input['caption'] ?? null,
242 $input['description'] ?? null,
243 $input['rating'] ?? null,
244 $input['display_embed'] ?? null,
245 $input['allow_download'] ?? null,
246 $input['privacy_setting'] ?? null
247 );
248 }
249 }
250