PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.9.5
Jetpack – WP Security, Backup, Speed, & Growth v12.9.5
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 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 / _inc / lib / class.media.php
jetpack / _inc / lib Last commit date
admin-pages 2 years ago core-api 2 years ago debugger 2 years ago markdown 2 years ago class-jetpack-ai-helper.php 2 years ago class-jetpack-currencies.php 5 years ago class-jetpack-google-drive-helper.php 3 years ago class-jetpack-instagram-gallery-helper.php 3 years ago class-jetpack-mapbox-helper.php 3 years ago class-jetpack-podcast-feed-locator.php 2 years ago class-jetpack-podcast-helper.php 2 years ago class-jetpack-recommendations.php 2 years ago class-jetpack-tweetstorm-helper.php 2 years ago class-jetpack-wizard.php 5 years ago class.color.php 2 years ago class.core-rest-api-endpoints.php 2 years ago class.jetpack-automatic-install-skin.php 2 years ago class.jetpack-iframe-embed.php 3 years ago class.jetpack-keyring-service-helper.php 3 years ago class.jetpack-password-checker.php 3 years ago class.jetpack-search-performance-logger.php 4 years ago class.media-extractor.php 3 years ago class.media-summary.php 2 years ago class.media.php 2 years ago components.php 3 years ago debugger.php 4 years ago functions.wp-notify.php 3 years ago icalendar-reader.php 2 years ago markdown.php 3 years ago plans.php 4 years ago plugins.php 4 years ago tonesque.php 2 years ago widgets.php 2 years ago
class.media.php
503 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 require_once JETPACK__PLUGIN_DIR . 'sal/class.json-api-date.php';
4
5 /**
6 * Class to handle different actions related to media.
7 */
8 class Jetpack_Media {
9 /**
10 * Original media meta data. Metadata key as stored by WP.
11 *
12 * @var string
13 */
14 const WP_ORIGINAL_MEDIA = '_wp_original_post_media';
15 /**
16 * Revision history. Metadata key as stored by WP.
17 *
18 * @var string
19 */
20 const WP_REVISION_HISTORY = '_wp_revision_history';
21 /**
22 * Maximum amount of revisions.
23 *
24 * @var int
25 */
26 const REVISION_HISTORY_MAXIMUM_AMOUNT = 0;
27 /**
28 * Image Alt. Metadata key as stored by WP.
29 *
30 * @var string
31 */
32 const WP_ATTACHMENT_IMAGE_ALT = '_wp_attachment_image_alt';
33
34 /**
35 * Generate a filename in function of the original filename of the media.
36 * The returned name has the `{basename}-{hash}-{random-number}.{ext}` shape.
37 * The hash is built according to the filename trying to avoid name collisions
38 * with other media files.
39 *
40 * @param number $media_id - media post ID.
41 * @param string $new_filename - the new filename.
42 * @return string A random filename.
43 */
44 public static function generate_new_filename( $media_id, $new_filename ) {
45 // Get the right filename extension.
46 $new_filename_paths = pathinfo( $new_filename );
47 $new_file_ext = $new_filename_paths['extension'];
48
49 // Get the file parts from the current attachment.
50 $current_file = get_attached_file( $media_id );
51 $current_file_parts = pathinfo( $current_file );
52 $current_file_ext = $current_file_parts['extension'];
53 $current_file_dirname = $current_file_parts['dirname'];
54
55 // Take out filename from the original file or from the current attachment.
56 $original_media = (array) self::get_original_media( $media_id );
57
58 if ( ! empty( $original_media ) ) {
59 $original_file_parts = pathinfo( $original_media['file'] );
60 $filename_base = $original_file_parts['filename'];
61 } else {
62 $filename_base = $current_file_parts['filename'];
63 }
64
65 // Add unique seed based on the filename.
66 $filename_base .= '-' . crc32( $filename_base ) . '-';
67
68 $number_suffix = time() . wp_rand( 100, 999 );
69
70 do {
71 $filename = $filename_base;
72 $filename .= "e{$number_suffix}";
73 $file_ext = $new_file_ext ? $new_file_ext : $current_file_ext;
74
75 $new_filename = "{$filename}.{$file_ext}";
76 $new_path = "{$current_file_dirname}/$new_filename";
77 ++$number_suffix;
78 } while ( file_exists( $new_path ) );
79
80 return $new_filename;
81 }
82
83 /**
84 * File urls use the post (image item) date to generate a folder path.
85 * Post dates can change, so we use the original date used in the `guid`
86 * url so edits can remain in the same folder. In the following function
87 * we capture a string in the format of `YYYY/MM` from the guid.
88 *
89 * For example with a guid of
90 * "http://test.files.wordpress.com/2016/10/test.png" the resulting string
91 * would be: "2016/10"
92 *
93 * @param int $media_id Attachment ID.
94 * @return string
95 */
96 private static function get_time_string_from_guid( $media_id ) {
97 $time = gmdate( 'Y/m', strtotime( current_time( 'mysql' ) ) );
98
99 $media = get_post( $media_id );
100 if ( $media ) {
101 $pattern = '/\/(\d{4}\/\d{2})\//';
102 preg_match( $pattern, $media->guid, $matches );
103 if ( count( $matches ) > 1 ) {
104 $time = $matches[1];
105 }
106 }
107 return $time;
108 }
109
110 /**
111 * Return an array of allowed mime_type items used to upload a media file.
112 *
113 * @param array $default_mime_types Array of mime types.
114 *
115 * @return array mime_type array
116 */
117 public static function get_allowed_mime_types( $default_mime_types ) {
118 return array_unique(
119 array_merge(
120 $default_mime_types,
121 array(
122 'application/msword', // .doc
123 'application/vnd.ms-powerpoint', // .ppt, .pps
124 'application/vnd.ms-excel', // .xls
125 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
126 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', // .ppsx
127 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
128 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
129 'application/vnd.oasis.opendocument.text', // .odt
130 'application/pdf', // .pdf
131 )
132 )
133 );
134 }
135
136 /**
137 * Checks that the mime type of the file
138 * is among those in a filterable list of mime types.
139 *
140 * @param string $file Path to file to get its mime type.
141 * @return bool
142 */
143 protected static function is_file_supported_for_sideloading( $file ) {
144 return jetpack_is_file_supported_for_sideloading( $file );
145 }
146
147 /**
148 * Save the given uploaded temporary file considering file type,
149 * correct location according to the original file path, etc.
150 * The file type control is done through of `jetpack_supported_media_sideload_types` filter,
151 * which allows define to the users their own file types list.
152 *
153 * Note this does not support sideloads, only uploads.
154 *
155 * @param array $file_array Data derived from `$_FILES` for an uploaded file.
156 * @param int $media_id Attachment ID.
157 * @return array|WP_Error an array with information about the new file saved or a WP_Error is something went wrong.
158 */
159 public static function save_temporary_file( $file_array, $media_id ) {
160 $tmp_filename = $file_array['tmp_name'];
161
162 if ( ! is_uploaded_file( $tmp_filename ) ) {
163 return new WP_Error( 'invalid_input', 'No media provided in input.' );
164 }
165
166 // add additional mime_types through of the `jetpack_supported_media_sideload_types` filter.
167 $mime_type_static_filter = array(
168 'Jetpack_Media',
169 'get_allowed_mime_types',
170 );
171
172 add_filter( 'jetpack_supported_media_sideload_types', $mime_type_static_filter );
173 if (
174 ! self::is_file_supported_for_sideloading( $tmp_filename ) &&
175 ! file_is_displayable_image( $tmp_filename )
176 ) {
177 return new WP_Error( 'invalid_input', 'Invalid file type.', 403 );
178 }
179 remove_filter( 'jetpack_supported_media_sideload_types', $mime_type_static_filter );
180
181 // generate a new file name.
182 $tmp_new_filename = self::generate_new_filename( $media_id, $file_array['name'] );
183
184 // start to create the parameters to move the temporal file.
185 $overrides = array( 'test_form' => false );
186
187 // get time according to the original filaname.
188 $time = self::get_time_string_from_guid( $media_id );
189
190 $file_array['name'] = $tmp_new_filename;
191 $file = wp_handle_upload( $file_array, $overrides, $time );
192
193 if ( isset( $file['error'] ) ) {
194 return new WP_Error( 'upload_error', $file['error'] );
195 }
196
197 return $file;
198 }
199
200 /**
201 * Return an object with an snapshot of a revision item.
202 *
203 * @param object $media_item - media post object.
204 * @return object a revision item
205 */
206 public static function get_snapshot( $media_item ) {
207 $current_file = get_attached_file( $media_item->ID );
208 $file_paths = pathinfo( $current_file );
209
210 $snapshot = array(
211 'date' => (string) WPCOM_JSON_API_Date::format_date( $media_item->post_modified_gmt, $media_item->post_modified ),
212 'URL' => (string) wp_get_attachment_url( $media_item->ID ),
213 'file' => (string) $file_paths['basename'],
214 'extension' => (string) $file_paths['extension'],
215 'mime_type' => (string) $media_item->post_mime_type,
216 'size' => (int) filesize( $current_file ),
217 );
218
219 return (object) $snapshot;
220 }
221
222 /**
223 * Add a new item into revision_history array.
224 *
225 * @param object $media_item - media post object.
226 * @param file $file - file recently added.
227 * @param bool $has_original_media - condition is the original media has been already added.
228 * @return bool `true` if the item has been added. Otherwise `false`.
229 */
230 public static function register_revision( $media_item, $file, $has_original_media ) {
231 if ( is_wp_error( $file ) || ! $has_original_media ) {
232 return false;
233 }
234
235 add_post_meta( $media_item->ID, self::WP_REVISION_HISTORY, self::get_snapshot( $media_item ) );
236 }
237 /**
238 * Return the `revision_history` of the given media.
239 *
240 * @param number $media_id - media post ID.
241 * @return array `revision_history` array
242 */
243 public static function get_revision_history( $media_id ) {
244 return array_reverse( get_post_meta( $media_id, self::WP_REVISION_HISTORY ) );
245 }
246
247 /**
248 * Return the original media data.
249 *
250 * @param int $media_id Attachment ID.
251 */
252 public static function get_original_media( $media_id ) {
253 $original = get_post_meta( $media_id, self::WP_ORIGINAL_MEDIA, true );
254 $original = $original ? $original : array();
255 return $original;
256 }
257
258 /**
259 * Delete a file.
260 *
261 * @param string $pathname Path name.
262 */
263 public static function delete_file( $pathname ) {
264 if ( ! file_exists( $pathname ) || ! is_file( $pathname ) ) {
265 // let's touch a fake file to try to `really` remove the media file.
266 touch( $pathname ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_touch
267 }
268
269 return wp_delete_file( $pathname );
270 }
271
272 /**
273 * Try to delete a file according to the dirname of
274 * the media attached file and the filename.
275 *
276 * @param int $media_id - media post ID.
277 * @param string $filename - basename of the file ( name-of-file.ext ).
278 *
279 * @return void
280 */
281 private static function delete_media_history_file( $media_id, $filename ) {
282 $attached_path = get_attached_file( $media_id );
283 $attached_parts = pathinfo( $attached_path );
284 $dirname = $attached_parts['dirname'];
285
286 $pathname = $dirname . '/' . $filename;
287
288 // remove thumbnails.
289 $metadata = wp_generate_attachment_metadata( $media_id, $pathname );
290
291 if ( isset( $metadata ) && isset( $metadata['sizes'] ) ) {
292 foreach ( $metadata['sizes'] as $properties ) {
293 self::delete_file( $dirname . '/' . $properties['file'] );
294 }
295 }
296
297 // remove primary file.
298 self::delete_file( $pathname );
299 }
300
301 /**
302 * Remove specific items from the `revision history` array
303 * depending on the given criteria: array(
304 * 'from' => (int) <from>,
305 * 'to' => (int) <to>,
306 * )
307 *
308 * Also, it removes the file defined in each item.
309 *
310 * @param int $media_id - media post ID.
311 * @param array $criteria - criteria to remove the items.
312 * @param array $revision_history - revision history array.
313 *
314 * @return array `revision_history` array updated.
315 */
316 public static function remove_items_from_revision_history( $media_id, $criteria, $revision_history ) {
317 if ( ! isset( $revision_history ) ) {
318 $revision_history = self::get_revision_history( $media_id );
319 }
320
321 $from = $criteria['from'];
322 $to = $criteria['to'] ? $criteria['to'] : ( $from + 1 );
323
324 for ( $i = $from; $i < $to; $i++ ) {
325 $removed_item = array_slice( $revision_history, $from, 1 );
326 if ( ! $removed_item ) {
327 break;
328 }
329
330 array_splice( $revision_history, $from, 1 );
331 self::delete_media_history_file( $media_id, $removed_item[0]->file );
332 }
333
334 // override all history items.
335 delete_post_meta( $media_id, self::WP_REVISION_HISTORY );
336 $revision_history = array_reverse( $revision_history );
337 foreach ( $revision_history as &$item ) {
338 add_post_meta( $media_id, self::WP_REVISION_HISTORY, $item );
339 }
340
341 return $revision_history;
342 }
343
344 /**
345 * Limit the number of items of the `revision_history` array.
346 * When the stack is overflowing the oldest item is remove from there (FIFO).
347 *
348 * @param int $media_id - media post ID.
349 * @param null|int $limit - maximum amount of items. 20 as default.
350 *
351 * @return array items removed from `revision_history`
352 */
353 public static function limit_revision_history( $media_id, $limit = null ) {
354 if ( $limit === null ) {
355 $limit = self::REVISION_HISTORY_MAXIMUM_AMOUNT;
356 }
357
358 $revision_history = self::get_revision_history( $media_id );
359
360 $total = count( $revision_history );
361
362 if ( $total < $limit ) {
363 return array();
364 }
365
366 self::remove_items_from_revision_history(
367 $media_id,
368 array(
369 'from' => $limit,
370 'to' => $total,
371 ),
372 $revision_history
373 );
374
375 return self::get_revision_history( $media_id );
376 }
377
378 /**
379 * Remove the original file and clean the post metadata.
380 *
381 * @param int $media_id - media post ID.
382 */
383 public static function clean_original_media( $media_id ) {
384 $original_file = self::get_original_media( $media_id );
385
386 if ( ! $original_file ) {
387 return null;
388 }
389
390 self::delete_media_history_file( $media_id, $original_file->file );
391 return delete_post_meta( $media_id, self::WP_ORIGINAL_MEDIA );
392 }
393
394 /**
395 * Clean `revision_history` of the given $media_id. it means:
396 * - remove all media files tied to the `revision_history` items.
397 * - clean `revision_history` meta data.
398 * - remove and clean the `original_media`
399 *
400 * @param int $media_id - media post ID.
401 *
402 * @return array results of removing these files
403 */
404 public static function clean_revision_history( $media_id ) {
405 self::clean_original_media( $media_id );
406
407 $revision_history = self::get_revision_history( $media_id );
408 $total = count( $revision_history );
409 $updated_history = array();
410
411 if ( $total < 1 ) {
412 return $updated_history;
413 }
414
415 $updated_history = self::remove_items_from_revision_history(
416 $media_id,
417 array(
418 'from' => 0,
419 'to' => $total,
420 ),
421 $revision_history
422 );
423
424 return $updated_history;
425 }
426
427 /**
428 * Edit media item process:
429 *
430 * - update attachment file
431 * - preserve original media file
432 * - trace revision history
433 *
434 * Note this does not support sideloads, only uploads.
435 *
436 * @param number $media_id - media post ID.
437 * @param array $file_array - Data derived from `$_FILES` for an uploaded file.
438 * @return {Post|WP_Error} Updated media item or a WP_Error is something went wrong.
439 */
440 public static function edit_media_file( $media_id, $file_array ) {
441 $media_item = get_post( $media_id );
442 $has_original_media = self::get_original_media( $media_id );
443
444 if ( ! $has_original_media ) {
445
446 // The first time that the media is updated
447 // the original media is stored into the revision_history.
448 $snapshot = self::get_snapshot( $media_item );
449 add_post_meta( $media_id, self::WP_ORIGINAL_MEDIA, $snapshot, true );
450 }
451
452 // Save temporary file in the correct location.
453 $uploaded_file = self::save_temporary_file( $file_array, $media_id );
454
455 if ( is_wp_error( $uploaded_file ) ) {
456 return $uploaded_file;
457 }
458
459 // Revision_history control.
460 self::register_revision( $media_item, $uploaded_file, $has_original_media );
461
462 $uploaded_path = $uploaded_file['file'];
463 $udpated_mime_type = $uploaded_file['type'];
464 $was_updated = update_attached_file( $media_id, $uploaded_path );
465
466 if ( ! $was_updated ) {
467 return new WP_Error( 'update_error', 'Media update error' );
468 }
469
470 // Check maximum amount of revision_history before updating the attachment metadata.
471 self::limit_revision_history( $media_id );
472
473 $new_metadata = wp_generate_attachment_metadata( $media_id, $uploaded_path );
474 wp_update_attachment_metadata( $media_id, $new_metadata );
475
476 $edited_action = wp_update_post(
477 (object) array(
478 'ID' => $media_id,
479 'post_mime_type' => $udpated_mime_type,
480 ),
481 true
482 );
483
484 if ( is_wp_error( $edited_action ) ) {
485 return $edited_action;
486 }
487
488 return $media_item;
489 }
490 }
491
492 // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move these functions to some other file.
493
494 /**
495 * Clean revision history when the media item is deleted.
496 *
497 * @param int $media_id Attachment ID.
498 */
499 function jetpack_clean_revision_history( $media_id ) {
500 Jetpack_Media::clean_revision_history( $media_id );
501 }
502 add_action( 'delete_attachment', 'jetpack_clean_revision_history' );
503