Passed
Push — main ( 16d49b...d78e29 )
by TARIQ
111:03
created
brighty/wp-admin/includes/media.php 1 patch
Indentation   +2467 added lines, -2467 removed lines patch added patch discarded remove patch
@@ -14,21 +14,21 @@  discard block
 block discarded – undo
14 14
  * @return string[] Default tabs.
15 15
  */
16 16
 function media_upload_tabs() {
17
-	$_default_tabs = array(
18
-		'type'     => __( 'From Computer' ), // Handler action suffix => tab text.
19
-		'type_url' => __( 'From URL' ),
20
-		'gallery'  => __( 'Gallery' ),
21
-		'library'  => __( 'Media Library' ),
22
-	);
23
-
24
-	/**
25
-	 * Filters the available tabs in the legacy (pre-3.5.0) media popup.
26
-	 *
27
-	 * @since 2.5.0
28
-	 *
29
-	 * @param string[] $_default_tabs An array of media tabs.
30
-	 */
31
-	return apply_filters( 'media_upload_tabs', $_default_tabs );
17
+    $_default_tabs = array(
18
+        'type'     => __( 'From Computer' ), // Handler action suffix => tab text.
19
+        'type_url' => __( 'From URL' ),
20
+        'gallery'  => __( 'Gallery' ),
21
+        'library'  => __( 'Media Library' ),
22
+    );
23
+
24
+    /**
25
+     * Filters the available tabs in the legacy (pre-3.5.0) media popup.
26
+     *
27
+     * @since 2.5.0
28
+     *
29
+     * @param string[] $_default_tabs An array of media tabs.
30
+     */
31
+    return apply_filters( 'media_upload_tabs', $_default_tabs );
32 32
 }
33 33
 
34 34
 /**
@@ -42,28 +42,28 @@  discard block
 block discarded – undo
42 42
  * @return array $tabs with gallery if post has image attachment
43 43
  */
44 44
 function update_gallery_tab( $tabs ) {
45
-	global $wpdb;
45
+    global $wpdb;
46 46
 
47
-	if ( ! isset( $_REQUEST['post_id'] ) ) {
48
-		unset( $tabs['gallery'] );
49
-		return $tabs;
50
-	}
47
+    if ( ! isset( $_REQUEST['post_id'] ) ) {
48
+        unset( $tabs['gallery'] );
49
+        return $tabs;
50
+    }
51 51
 
52
-	$post_id = (int) $_REQUEST['post_id'];
52
+    $post_id = (int) $_REQUEST['post_id'];
53 53
 
54
-	if ( $post_id ) {
55
-		$attachments = (int) $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_parent = %d", $post_id ) );
56
-	}
54
+    if ( $post_id ) {
55
+        $attachments = (int) $wpdb->get_var( $wpdb->prepare( "SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_parent = %d", $post_id ) );
56
+    }
57 57
 
58
-	if ( empty( $attachments ) ) {
59
-		unset( $tabs['gallery'] );
60
-		return $tabs;
61
-	}
58
+    if ( empty( $attachments ) ) {
59
+        unset( $tabs['gallery'] );
60
+        return $tabs;
61
+    }
62 62
 
63
-	/* translators: %s: Number of attachments. */
64
-	$tabs['gallery'] = sprintf( __( 'Gallery (%s)' ), "<span id='attachments-count'>$attachments</span>" );
63
+    /* translators: %s: Number of attachments. */
64
+    $tabs['gallery'] = sprintf( __( 'Gallery (%s)' ), "<span id='attachments-count'>$attachments</span>" );
65 65
 
66
-	return $tabs;
66
+    return $tabs;
67 67
 }
68 68
 
69 69
 /**
@@ -74,44 +74,44 @@  discard block
 block discarded – undo
74 74
  * @global string $redir_tab
75 75
  */
76 76
 function the_media_upload_tabs() {
77
-	global $redir_tab;
78
-	$tabs    = media_upload_tabs();
79
-	$default = 'type';
80
-
81
-	if ( ! empty( $tabs ) ) {
82
-		echo "<ul id='sidemenu'>\n";
83
-
84
-		if ( isset( $redir_tab ) && array_key_exists( $redir_tab, $tabs ) ) {
85
-			$current = $redir_tab;
86
-		} elseif ( isset( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $tabs ) ) {
87
-			$current = $_GET['tab'];
88
-		} else {
89
-			/** This filter is documented in wp-admin/media-upload.php */
90
-			$current = apply_filters( 'media_upload_default_tab', $default );
91
-		}
92
-
93
-		foreach ( $tabs as $callback => $text ) {
94
-			$class = '';
95
-
96
-			if ( $current == $callback ) {
97
-				$class = " class='current'";
98
-			}
99
-
100
-			$href = add_query_arg(
101
-				array(
102
-					'tab'            => $callback,
103
-					's'              => false,
104
-					'paged'          => false,
105
-					'post_mime_type' => false,
106
-					'm'              => false,
107
-				)
108
-			);
109
-			$link = "<a href='" . esc_url( $href ) . "'$class>$text</a>";
110
-			echo "\t<li id='" . esc_attr( "tab-$callback" ) . "'>$link</li>\n";
111
-		}
112
-
113
-		echo "</ul>\n";
114
-	}
77
+    global $redir_tab;
78
+    $tabs    = media_upload_tabs();
79
+    $default = 'type';
80
+
81
+    if ( ! empty( $tabs ) ) {
82
+        echo "<ul id='sidemenu'>\n";
83
+
84
+        if ( isset( $redir_tab ) && array_key_exists( $redir_tab, $tabs ) ) {
85
+            $current = $redir_tab;
86
+        } elseif ( isset( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $tabs ) ) {
87
+            $current = $_GET['tab'];
88
+        } else {
89
+            /** This filter is documented in wp-admin/media-upload.php */
90
+            $current = apply_filters( 'media_upload_default_tab', $default );
91
+        }
92
+
93
+        foreach ( $tabs as $callback => $text ) {
94
+            $class = '';
95
+
96
+            if ( $current == $callback ) {
97
+                $class = " class='current'";
98
+            }
99
+
100
+            $href = add_query_arg(
101
+                array(
102
+                    'tab'            => $callback,
103
+                    's'              => false,
104
+                    'paged'          => false,
105
+                    'post_mime_type' => false,
106
+                    'm'              => false,
107
+                )
108
+            );
109
+            $link = "<a href='" . esc_url( $href ) . "'$class>$text</a>";
110
+            echo "\t<li id='" . esc_attr( "tab-$callback" ) . "'>$link</li>\n";
111
+        }
112
+
113
+        echo "</ul>\n";
114
+    }
115 115
 }
116 116
 
117 117
 /**
@@ -132,42 +132,42 @@  discard block
 block discarded – undo
132 132
  */
133 133
 function get_image_send_to_editor( $id, $caption, $title, $align, $url = '', $rel = false, $size = 'medium', $alt = '' ) {
134 134
 
135
-	$html = get_image_tag( $id, $alt, '', $align, $size );
136
-
137
-	if ( $rel ) {
138
-		if ( is_string( $rel ) ) {
139
-			$rel = ' rel="' . esc_attr( $rel ) . '"';
140
-		} else {
141
-			$rel = ' rel="attachment wp-att-' . (int) $id . '"';
142
-		}
143
-	} else {
144
-		$rel = '';
145
-	}
146
-
147
-	if ( $url ) {
148
-		$html = '<a href="' . esc_attr( $url ) . '"' . $rel . '>' . $html . '</a>';
149
-	}
150
-
151
-	/**
152
-	 * Filters the image HTML markup to send to the editor when inserting an image.
153
-	 *
154
-	 * @since 2.5.0
155
-	 * @since 5.6.0 The `$rel` parameter was added.
156
-	 *
157
-	 * @param string       $html    The image HTML markup to send.
158
-	 * @param int          $id      The attachment ID.
159
-	 * @param string       $caption The image caption.
160
-	 * @param string       $title   The image title.
161
-	 * @param string       $align   The image alignment.
162
-	 * @param string       $url     The image source URL.
163
-	 * @param string|int[] $size    Requested image size. Can be any registered image size name, or
164
-	 *                              an array of width and height values in pixels (in that order).
165
-	 * @param string       $alt     The image alternative, or alt, text.
166
-	 * @param string       $rel     The image rel attribute.
167
-	 */
168
-	$html = apply_filters( 'image_send_to_editor', $html, $id, $caption, $title, $align, $url, $size, $alt, $rel );
169
-
170
-	return $html;
135
+    $html = get_image_tag( $id, $alt, '', $align, $size );
136
+
137
+    if ( $rel ) {
138
+        if ( is_string( $rel ) ) {
139
+            $rel = ' rel="' . esc_attr( $rel ) . '"';
140
+        } else {
141
+            $rel = ' rel="attachment wp-att-' . (int) $id . '"';
142
+        }
143
+    } else {
144
+        $rel = '';
145
+    }
146
+
147
+    if ( $url ) {
148
+        $html = '<a href="' . esc_attr( $url ) . '"' . $rel . '>' . $html . '</a>';
149
+    }
150
+
151
+    /**
152
+     * Filters the image HTML markup to send to the editor when inserting an image.
153
+     *
154
+     * @since 2.5.0
155
+     * @since 5.6.0 The `$rel` parameter was added.
156
+     *
157
+     * @param string       $html    The image HTML markup to send.
158
+     * @param int          $id      The attachment ID.
159
+     * @param string       $caption The image caption.
160
+     * @param string       $title   The image title.
161
+     * @param string       $align   The image alignment.
162
+     * @param string       $url     The image source URL.
163
+     * @param string|int[] $size    Requested image size. Can be any registered image size name, or
164
+     *                              an array of width and height values in pixels (in that order).
165
+     * @param string       $alt     The image alternative, or alt, text.
166
+     * @param string       $rel     The image rel attribute.
167
+     */
168
+    $html = apply_filters( 'image_send_to_editor', $html, $id, $caption, $title, $align, $url, $size, $alt, $rel );
169
+
170
+    return $html;
171 171
 }
172 172
 
173 173
 /**
@@ -187,66 +187,66 @@  discard block
 block discarded – undo
187 187
  */
188 188
 function image_add_caption( $html, $id, $caption, $title, $align, $url, $size, $alt = '' ) {
189 189
 
190
-	/**
191
-	 * Filters the caption text.
192
-	 *
193
-	 * Note: If the caption text is empty, the caption shortcode will not be appended
194
-	 * to the image HTML when inserted into the editor.
195
-	 *
196
-	 * Passing an empty value also prevents the {@see 'image_add_caption_shortcode'}
197
-	 * Filters from being evaluated at the end of image_add_caption().
198
-	 *
199
-	 * @since 4.1.0
200
-	 *
201
-	 * @param string $caption The original caption text.
202
-	 * @param int    $id      The attachment ID.
203
-	 */
204
-	$caption = apply_filters( 'image_add_caption_text', $caption, $id );
205
-
206
-	/**
207
-	 * Filters whether to disable captions.
208
-	 *
209
-	 * Prevents image captions from being appended to image HTML when inserted into the editor.
210
-	 *
211
-	 * @since 2.6.0
212
-	 *
213
-	 * @param bool $bool Whether to disable appending captions. Returning true from the filter
214
-	 *                   will disable captions. Default empty string.
215
-	 */
216
-	if ( empty( $caption ) || apply_filters( 'disable_captions', '' ) ) {
217
-		return $html;
218
-	}
219
-
220
-	$id = ( 0 < (int) $id ) ? 'attachment_' . $id : '';
221
-
222
-	if ( ! preg_match( '/width=["\']([0-9]+)/', $html, $matches ) ) {
223
-		return $html;
224
-	}
225
-
226
-	$width = $matches[1];
227
-
228
-	$caption = str_replace( array( "\r\n", "\r" ), "\n", $caption );
229
-	$caption = preg_replace_callback( '/<[a-zA-Z0-9]+(?: [^<>]+>)*/', '_cleanup_image_add_caption', $caption );
230
-
231
-	// Convert any remaining line breaks to <br />.
232
-	$caption = preg_replace( '/[ \n\t]*\n[ \t]*/', '<br />', $caption );
233
-
234
-	$html = preg_replace( '/(class=["\'][^\'"]*)align(none|left|right|center)\s?/', '$1', $html );
235
-	if ( empty( $align ) ) {
236
-		$align = 'none';
237
-	}
238
-
239
-	$shcode = '[caption id="' . $id . '" align="align' . $align . '" width="' . $width . '"]' . $html . ' ' . $caption . '[/caption]';
240
-
241
-	/**
242
-	 * Filters the image HTML markup including the caption shortcode.
243
-	 *
244
-	 * @since 2.6.0
245
-	 *
246
-	 * @param string $shcode The image HTML markup with caption shortcode.
247
-	 * @param string $html   The image HTML markup.
248
-	 */
249
-	return apply_filters( 'image_add_caption_shortcode', $shcode, $html );
190
+    /**
191
+     * Filters the caption text.
192
+     *
193
+     * Note: If the caption text is empty, the caption shortcode will not be appended
194
+     * to the image HTML when inserted into the editor.
195
+     *
196
+     * Passing an empty value also prevents the {@see 'image_add_caption_shortcode'}
197
+     * Filters from being evaluated at the end of image_add_caption().
198
+     *
199
+     * @since 4.1.0
200
+     *
201
+     * @param string $caption The original caption text.
202
+     * @param int    $id      The attachment ID.
203
+     */
204
+    $caption = apply_filters( 'image_add_caption_text', $caption, $id );
205
+
206
+    /**
207
+     * Filters whether to disable captions.
208
+     *
209
+     * Prevents image captions from being appended to image HTML when inserted into the editor.
210
+     *
211
+     * @since 2.6.0
212
+     *
213
+     * @param bool $bool Whether to disable appending captions. Returning true from the filter
214
+     *                   will disable captions. Default empty string.
215
+     */
216
+    if ( empty( $caption ) || apply_filters( 'disable_captions', '' ) ) {
217
+        return $html;
218
+    }
219
+
220
+    $id = ( 0 < (int) $id ) ? 'attachment_' . $id : '';
221
+
222
+    if ( ! preg_match( '/width=["\']([0-9]+)/', $html, $matches ) ) {
223
+        return $html;
224
+    }
225
+
226
+    $width = $matches[1];
227
+
228
+    $caption = str_replace( array( "\r\n", "\r" ), "\n", $caption );
229
+    $caption = preg_replace_callback( '/<[a-zA-Z0-9]+(?: [^<>]+>)*/', '_cleanup_image_add_caption', $caption );
230
+
231
+    // Convert any remaining line breaks to <br />.
232
+    $caption = preg_replace( '/[ \n\t]*\n[ \t]*/', '<br />', $caption );
233
+
234
+    $html = preg_replace( '/(class=["\'][^\'"]*)align(none|left|right|center)\s?/', '$1', $html );
235
+    if ( empty( $align ) ) {
236
+        $align = 'none';
237
+    }
238
+
239
+    $shcode = '[caption id="' . $id . '" align="align' . $align . '" width="' . $width . '"]' . $html . ' ' . $caption . '[/caption]';
240
+
241
+    /**
242
+     * Filters the image HTML markup including the caption shortcode.
243
+     *
244
+     * @since 2.6.0
245
+     *
246
+     * @param string $shcode The image HTML markup with caption shortcode.
247
+     * @param string $html   The image HTML markup.
248
+     */
249
+    return apply_filters( 'image_add_caption_shortcode', $shcode, $html );
250 250
 }
251 251
 
252 252
 /**
@@ -256,8 +256,8 @@  discard block
 block discarded – undo
256 256
  * @since 3.4.0
257 257
  */
258 258
 function _cleanup_image_add_caption( $matches ) {
259
-	// Remove any line breaks from inside the tags.
260
-	return preg_replace( '/[\r\n\t]+/', ' ', $matches[0] );
259
+    // Remove any line breaks from inside the tags.
260
+    return preg_replace( '/[\r\n\t]+/', ' ', $matches[0] );
261 261
 }
262 262
 
263 263
 /**
@@ -268,13 +268,13 @@  discard block
 block discarded – undo
268 268
  * @param string $html
269 269
  */
270 270
 function media_send_to_editor( $html ) {
271
-	?>
271
+    ?>
272 272
 	<script type="text/javascript">
273 273
 	var win = window.dialogArguments || opener || parent || top;
274 274
 	win.send_to_editor( <?php echo wp_json_encode( $html ); ?> );
275 275
 	</script>
276 276
 	<?php
277
-	exit;
277
+    exit;
278 278
 }
279 279
 
280 280
 /**
@@ -290,147 +290,147 @@  discard block
 block discarded – undo
290 290
  * @return int|WP_Error ID of the attachment or a WP_Error object on failure.
291 291
  */
292 292
 function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrides = array( 'test_form' => false ) ) {
293
-	$time = current_time( 'mysql' );
294
-	$post = get_post( $post_id );
295
-
296
-	if ( $post ) {
297
-		// The post date doesn't usually matter for pages, so don't backdate this upload.
298
-		if ( 'page' !== $post->post_type && substr( $post->post_date, 0, 4 ) > 0 ) {
299
-			$time = $post->post_date;
300
-		}
301
-	}
302
-
303
-	$file = wp_handle_upload( $_FILES[ $file_id ], $overrides, $time );
304
-
305
-	if ( isset( $file['error'] ) ) {
306
-		return new WP_Error( 'upload_error', $file['error'] );
307
-	}
308
-
309
-	$name = $_FILES[ $file_id ]['name'];
310
-	$ext  = pathinfo( $name, PATHINFO_EXTENSION );
311
-	$name = wp_basename( $name, ".$ext" );
312
-
313
-	$url     = $file['url'];
314
-	$type    = $file['type'];
315
-	$file    = $file['file'];
316
-	$title   = sanitize_text_field( $name );
317
-	$content = '';
318
-	$excerpt = '';
319
-
320
-	if ( preg_match( '#^audio#', $type ) ) {
321
-		$meta = wp_read_audio_metadata( $file );
322
-
323
-		if ( ! empty( $meta['title'] ) ) {
324
-			$title = $meta['title'];
325
-		}
326
-
327
-		if ( ! empty( $title ) ) {
328
-
329
-			if ( ! empty( $meta['album'] ) && ! empty( $meta['artist'] ) ) {
330
-				/* translators: 1: Audio track title, 2: Album title, 3: Artist name. */
331
-				$content .= sprintf( __( '"%1$s" from %2$s by %3$s.' ), $title, $meta['album'], $meta['artist'] );
332
-			} elseif ( ! empty( $meta['album'] ) ) {
333
-				/* translators: 1: Audio track title, 2: Album title. */
334
-				$content .= sprintf( __( '"%1$s" from %2$s.' ), $title, $meta['album'] );
335
-			} elseif ( ! empty( $meta['artist'] ) ) {
336
-				/* translators: 1: Audio track title, 2: Artist name. */
337
-				$content .= sprintf( __( '"%1$s" by %2$s.' ), $title, $meta['artist'] );
338
-			} else {
339
-				/* translators: %s: Audio track title. */
340
-				$content .= sprintf( __( '"%s".' ), $title );
341
-			}
342
-		} elseif ( ! empty( $meta['album'] ) ) {
343
-
344
-			if ( ! empty( $meta['artist'] ) ) {
345
-				/* translators: 1: Audio album title, 2: Artist name. */
346
-				$content .= sprintf( __( '%1$s by %2$s.' ), $meta['album'], $meta['artist'] );
347
-			} else {
348
-				$content .= $meta['album'] . '.';
349
-			}
350
-		} elseif ( ! empty( $meta['artist'] ) ) {
351
-
352
-			$content .= $meta['artist'] . '.';
353
-
354
-		}
355
-
356
-		if ( ! empty( $meta['year'] ) ) {
357
-			/* translators: Audio file track information. %d: Year of audio track release. */
358
-			$content .= ' ' . sprintf( __( 'Released: %d.' ), $meta['year'] );
359
-		}
360
-
361
-		if ( ! empty( $meta['track_number'] ) ) {
362
-			$track_number = explode( '/', $meta['track_number'] );
363
-
364
-			if ( is_numeric( $track_number[0] ) ) {
365
-				if ( isset( $track_number[1] ) && is_numeric( $track_number[1] ) ) {
366
-					$content .= ' ' . sprintf(
367
-						/* translators: Audio file track information. 1: Audio track number, 2: Total audio tracks. */
368
-						__( 'Track %1$s of %2$s.' ),
369
-						number_format_i18n( $track_number[0] ),
370
-						number_format_i18n( $track_number[1] )
371
-					);
372
-				} else {
373
-					$content .= ' ' . sprintf(
374
-						/* translators: Audio file track information. %s: Audio track number. */
375
-						__( 'Track %s.' ),
376
-						number_format_i18n( $track_number[0] )
377
-					);
378
-				}
379
-			}
380
-		}
381
-
382
-		if ( ! empty( $meta['genre'] ) ) {
383
-			/* translators: Audio file genre information. %s: Audio genre name. */
384
-			$content .= ' ' . sprintf( __( 'Genre: %s.' ), $meta['genre'] );
385
-		}
386
-
387
-		// Use image exif/iptc data for title and caption defaults if possible.
388
-	} elseif ( 0 === strpos( $type, 'image/' ) ) {
389
-		$image_meta = wp_read_image_metadata( $file );
390
-
391
-		if ( $image_meta ) {
392
-			if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
393
-				$title = $image_meta['title'];
394
-			}
395
-
396
-			if ( trim( $image_meta['caption'] ) ) {
397
-				$excerpt = $image_meta['caption'];
398
-			}
399
-		}
400
-	}
401
-
402
-	// Construct the attachment array.
403
-	$attachment = array_merge(
404
-		array(
405
-			'post_mime_type' => $type,
406
-			'guid'           => $url,
407
-			'post_parent'    => $post_id,
408
-			'post_title'     => $title,
409
-			'post_content'   => $content,
410
-			'post_excerpt'   => $excerpt,
411
-		),
412
-		$post_data
413
-	);
414
-
415
-	// This should never be set as it would then overwrite an existing attachment.
416
-	unset( $attachment['ID'] );
417
-
418
-	// Save the data.
419
-	$attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
420
-
421
-	if ( ! is_wp_error( $attachment_id ) ) {
422
-		// Set a custom header with the attachment_id.
423
-		// Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
424
-		if ( ! headers_sent() ) {
425
-			header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
426
-		}
427
-
428
-		// The image sub-sizes are created during wp_generate_attachment_metadata().
429
-		// This is generally slow and may cause timeouts or out of memory errors.
430
-		wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
431
-	}
432
-
433
-	return $attachment_id;
293
+    $time = current_time( 'mysql' );
294
+    $post = get_post( $post_id );
295
+
296
+    if ( $post ) {
297
+        // The post date doesn't usually matter for pages, so don't backdate this upload.
298
+        if ( 'page' !== $post->post_type && substr( $post->post_date, 0, 4 ) > 0 ) {
299
+            $time = $post->post_date;
300
+        }
301
+    }
302
+
303
+    $file = wp_handle_upload( $_FILES[ $file_id ], $overrides, $time );
304
+
305
+    if ( isset( $file['error'] ) ) {
306
+        return new WP_Error( 'upload_error', $file['error'] );
307
+    }
308
+
309
+    $name = $_FILES[ $file_id ]['name'];
310
+    $ext  = pathinfo( $name, PATHINFO_EXTENSION );
311
+    $name = wp_basename( $name, ".$ext" );
312
+
313
+    $url     = $file['url'];
314
+    $type    = $file['type'];
315
+    $file    = $file['file'];
316
+    $title   = sanitize_text_field( $name );
317
+    $content = '';
318
+    $excerpt = '';
319
+
320
+    if ( preg_match( '#^audio#', $type ) ) {
321
+        $meta = wp_read_audio_metadata( $file );
322
+
323
+        if ( ! empty( $meta['title'] ) ) {
324
+            $title = $meta['title'];
325
+        }
326
+
327
+        if ( ! empty( $title ) ) {
328
+
329
+            if ( ! empty( $meta['album'] ) && ! empty( $meta['artist'] ) ) {
330
+                /* translators: 1: Audio track title, 2: Album title, 3: Artist name. */
331
+                $content .= sprintf( __( '"%1$s" from %2$s by %3$s.' ), $title, $meta['album'], $meta['artist'] );
332
+            } elseif ( ! empty( $meta['album'] ) ) {
333
+                /* translators: 1: Audio track title, 2: Album title. */
334
+                $content .= sprintf( __( '"%1$s" from %2$s.' ), $title, $meta['album'] );
335
+            } elseif ( ! empty( $meta['artist'] ) ) {
336
+                /* translators: 1: Audio track title, 2: Artist name. */
337
+                $content .= sprintf( __( '"%1$s" by %2$s.' ), $title, $meta['artist'] );
338
+            } else {
339
+                /* translators: %s: Audio track title. */
340
+                $content .= sprintf( __( '"%s".' ), $title );
341
+            }
342
+        } elseif ( ! empty( $meta['album'] ) ) {
343
+
344
+            if ( ! empty( $meta['artist'] ) ) {
345
+                /* translators: 1: Audio album title, 2: Artist name. */
346
+                $content .= sprintf( __( '%1$s by %2$s.' ), $meta['album'], $meta['artist'] );
347
+            } else {
348
+                $content .= $meta['album'] . '.';
349
+            }
350
+        } elseif ( ! empty( $meta['artist'] ) ) {
351
+
352
+            $content .= $meta['artist'] . '.';
353
+
354
+        }
355
+
356
+        if ( ! empty( $meta['year'] ) ) {
357
+            /* translators: Audio file track information. %d: Year of audio track release. */
358
+            $content .= ' ' . sprintf( __( 'Released: %d.' ), $meta['year'] );
359
+        }
360
+
361
+        if ( ! empty( $meta['track_number'] ) ) {
362
+            $track_number = explode( '/', $meta['track_number'] );
363
+
364
+            if ( is_numeric( $track_number[0] ) ) {
365
+                if ( isset( $track_number[1] ) && is_numeric( $track_number[1] ) ) {
366
+                    $content .= ' ' . sprintf(
367
+                        /* translators: Audio file track information. 1: Audio track number, 2: Total audio tracks. */
368
+                        __( 'Track %1$s of %2$s.' ),
369
+                        number_format_i18n( $track_number[0] ),
370
+                        number_format_i18n( $track_number[1] )
371
+                    );
372
+                } else {
373
+                    $content .= ' ' . sprintf(
374
+                        /* translators: Audio file track information. %s: Audio track number. */
375
+                        __( 'Track %s.' ),
376
+                        number_format_i18n( $track_number[0] )
377
+                    );
378
+                }
379
+            }
380
+        }
381
+
382
+        if ( ! empty( $meta['genre'] ) ) {
383
+            /* translators: Audio file genre information. %s: Audio genre name. */
384
+            $content .= ' ' . sprintf( __( 'Genre: %s.' ), $meta['genre'] );
385
+        }
386
+
387
+        // Use image exif/iptc data for title and caption defaults if possible.
388
+    } elseif ( 0 === strpos( $type, 'image/' ) ) {
389
+        $image_meta = wp_read_image_metadata( $file );
390
+
391
+        if ( $image_meta ) {
392
+            if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
393
+                $title = $image_meta['title'];
394
+            }
395
+
396
+            if ( trim( $image_meta['caption'] ) ) {
397
+                $excerpt = $image_meta['caption'];
398
+            }
399
+        }
400
+    }
401
+
402
+    // Construct the attachment array.
403
+    $attachment = array_merge(
404
+        array(
405
+            'post_mime_type' => $type,
406
+            'guid'           => $url,
407
+            'post_parent'    => $post_id,
408
+            'post_title'     => $title,
409
+            'post_content'   => $content,
410
+            'post_excerpt'   => $excerpt,
411
+        ),
412
+        $post_data
413
+    );
414
+
415
+    // This should never be set as it would then overwrite an existing attachment.
416
+    unset( $attachment['ID'] );
417
+
418
+    // Save the data.
419
+    $attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
420
+
421
+    if ( ! is_wp_error( $attachment_id ) ) {
422
+        // Set a custom header with the attachment_id.
423
+        // Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
424
+        if ( ! headers_sent() ) {
425
+            header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
426
+        }
427
+
428
+        // The image sub-sizes are created during wp_generate_attachment_metadata().
429
+        // This is generally slow and may cause timeouts or out of memory errors.
430
+        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
431
+    }
432
+
433
+    return $attachment_id;
434 434
 }
435 435
 
436 436
 /**
@@ -446,71 +446,71 @@  discard block
 block discarded – undo
446 446
  * @return int|WP_Error The ID of the attachment or a WP_Error on failure.
447 447
  */
448 448
 function media_handle_sideload( $file_array, $post_id = 0, $desc = null, $post_data = array() ) {
449
-	$overrides = array( 'test_form' => false );
450
-
451
-	if ( isset( $post_data['post_date'] ) && substr( $post_data['post_date'], 0, 4 ) > 0 ) {
452
-		$time = $post_data['post_date'];
453
-	} else {
454
-		$post = get_post( $post_id );
455
-		if ( $post && substr( $post->post_date, 0, 4 ) > 0 ) {
456
-			$time = $post->post_date;
457
-		} else {
458
-			$time = current_time( 'mysql' );
459
-		}
460
-	}
461
-
462
-	$file = wp_handle_sideload( $file_array, $overrides, $time );
463
-
464
-	if ( isset( $file['error'] ) ) {
465
-		return new WP_Error( 'upload_error', $file['error'] );
466
-	}
467
-
468
-	$url     = $file['url'];
469
-	$type    = $file['type'];
470
-	$file    = $file['file'];
471
-	$title   = preg_replace( '/\.[^.]+$/', '', wp_basename( $file ) );
472
-	$content = '';
473
-
474
-	// Use image exif/iptc data for title and caption defaults if possible.
475
-	$image_meta = wp_read_image_metadata( $file );
476
-
477
-	if ( $image_meta ) {
478
-		if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
479
-			$title = $image_meta['title'];
480
-		}
481
-
482
-		if ( trim( $image_meta['caption'] ) ) {
483
-			$content = $image_meta['caption'];
484
-		}
485
-	}
486
-
487
-	if ( isset( $desc ) ) {
488
-		$title = $desc;
489
-	}
490
-
491
-	// Construct the attachment array.
492
-	$attachment = array_merge(
493
-		array(
494
-			'post_mime_type' => $type,
495
-			'guid'           => $url,
496
-			'post_parent'    => $post_id,
497
-			'post_title'     => $title,
498
-			'post_content'   => $content,
499
-		),
500
-		$post_data
501
-	);
502
-
503
-	// This should never be set as it would then overwrite an existing attachment.
504
-	unset( $attachment['ID'] );
505
-
506
-	// Save the attachment metadata.
507
-	$attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
508
-
509
-	if ( ! is_wp_error( $attachment_id ) ) {
510
-		wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
511
-	}
512
-
513
-	return $attachment_id;
449
+    $overrides = array( 'test_form' => false );
450
+
451
+    if ( isset( $post_data['post_date'] ) && substr( $post_data['post_date'], 0, 4 ) > 0 ) {
452
+        $time = $post_data['post_date'];
453
+    } else {
454
+        $post = get_post( $post_id );
455
+        if ( $post && substr( $post->post_date, 0, 4 ) > 0 ) {
456
+            $time = $post->post_date;
457
+        } else {
458
+            $time = current_time( 'mysql' );
459
+        }
460
+    }
461
+
462
+    $file = wp_handle_sideload( $file_array, $overrides, $time );
463
+
464
+    if ( isset( $file['error'] ) ) {
465
+        return new WP_Error( 'upload_error', $file['error'] );
466
+    }
467
+
468
+    $url     = $file['url'];
469
+    $type    = $file['type'];
470
+    $file    = $file['file'];
471
+    $title   = preg_replace( '/\.[^.]+$/', '', wp_basename( $file ) );
472
+    $content = '';
473
+
474
+    // Use image exif/iptc data for title and caption defaults if possible.
475
+    $image_meta = wp_read_image_metadata( $file );
476
+
477
+    if ( $image_meta ) {
478
+        if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
479
+            $title = $image_meta['title'];
480
+        }
481
+
482
+        if ( trim( $image_meta['caption'] ) ) {
483
+            $content = $image_meta['caption'];
484
+        }
485
+    }
486
+
487
+    if ( isset( $desc ) ) {
488
+        $title = $desc;
489
+    }
490
+
491
+    // Construct the attachment array.
492
+    $attachment = array_merge(
493
+        array(
494
+            'post_mime_type' => $type,
495
+            'guid'           => $url,
496
+            'post_parent'    => $post_id,
497
+            'post_title'     => $title,
498
+            'post_content'   => $content,
499
+        ),
500
+        $post_data
501
+    );
502
+
503
+    // This should never be set as it would then overwrite an existing attachment.
504
+    unset( $attachment['ID'] );
505
+
506
+    // Save the attachment metadata.
507
+    $attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
508
+
509
+    if ( ! is_wp_error( $attachment_id ) ) {
510
+        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
511
+    }
512
+
513
+    return $attachment_id;
514 514
 }
515 515
 
516 516
 /**
@@ -526,81 +526,81 @@  discard block
 block discarded – undo
526 526
  * @param mixed    ...$args      Optional additional parameters to pass to the callback function when it's called.
527 527
  */
528 528
 function wp_iframe( $content_func, ...$args ) {
529
-	_wp_admin_html_begin();
530
-	?>
529
+    _wp_admin_html_begin();
530
+    ?>
531 531
 	<title><?php bloginfo( 'name' ); ?> &rsaquo; <?php _e( 'Uploads' ); ?> &#8212; <?php _e( 'WordPress' ); ?></title>
532 532
 	<?php
533 533
 
534
-	wp_enqueue_style( 'colors' );
535
-	// Check callback name for 'media'.
536
-	if (
537
-		( is_array( $content_func ) && ! empty( $content_func[1] ) && 0 === strpos( (string) $content_func[1], 'media' ) ) ||
538
-		( ! is_array( $content_func ) && 0 === strpos( $content_func, 'media' ) )
539
-	) {
540
-		wp_enqueue_style( 'deprecated-media' );
541
-	}
534
+    wp_enqueue_style( 'colors' );
535
+    // Check callback name for 'media'.
536
+    if (
537
+        ( is_array( $content_func ) && ! empty( $content_func[1] ) && 0 === strpos( (string) $content_func[1], 'media' ) ) ||
538
+        ( ! is_array( $content_func ) && 0 === strpos( $content_func, 'media' ) )
539
+    ) {
540
+        wp_enqueue_style( 'deprecated-media' );
541
+    }
542 542
 
543
-	?>
543
+    ?>
544 544
 	<script type="text/javascript">
545 545
 	addLoadEvent = function(func){if(typeof jQuery!=='undefined')jQuery(function(){func();});else if(typeof wpOnload!=='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
546 546
 	var ajaxurl = '<?php echo esc_js( admin_url( 'admin-ajax.php', 'relative' ) ); ?>', pagenow = 'media-upload-popup', adminpage = 'media-upload-popup',
547 547
 	isRtl = <?php echo (int) is_rtl(); ?>;
548 548
 	</script>
549 549
 	<?php
550
-	/** This action is documented in wp-admin/admin-header.php */
551
-	do_action( 'admin_enqueue_scripts', 'media-upload-popup' );
552
-
553
-	/**
554
-	 * Fires when admin styles enqueued for the legacy (pre-3.5.0) media upload popup are printed.
555
-	 *
556
-	 * @since 2.9.0
557
-	 */
558
-	do_action( 'admin_print_styles-media-upload-popup' );  // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
559
-
560
-	/** This action is documented in wp-admin/admin-header.php */
561
-	do_action( 'admin_print_styles' );
562
-
563
-	/**
564
-	 * Fires when admin scripts enqueued for the legacy (pre-3.5.0) media upload popup are printed.
565
-	 *
566
-	 * @since 2.9.0
567
-	 */
568
-	do_action( 'admin_print_scripts-media-upload-popup' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
569
-
570
-	/** This action is documented in wp-admin/admin-header.php */
571
-	do_action( 'admin_print_scripts' );
572
-
573
-	/**
574
-	 * Fires when scripts enqueued for the admin header for the legacy (pre-3.5.0)
575
-	 * media upload popup are printed.
576
-	 *
577
-	 * @since 2.9.0
578
-	 */
579
-	do_action( 'admin_head-media-upload-popup' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
580
-
581
-	/** This action is documented in wp-admin/admin-header.php */
582
-	do_action( 'admin_head' );
583
-
584
-	if ( is_string( $content_func ) ) {
585
-		/**
586
-		 * Fires in the admin header for each specific form tab in the legacy
587
-		 * (pre-3.5.0) media upload popup.
588
-		 *
589
-		 * The dynamic portion of the hook name, `$content_func`, refers to the form
590
-		 * callback for the media upload type.
591
-		 *
592
-		 * @since 2.5.0
593
-		 */
594
-		do_action( "admin_head_{$content_func}" );
595
-	}
596
-
597
-	$body_id_attr = '';
598
-
599
-	if ( isset( $GLOBALS['body_id'] ) ) {
600
-		$body_id_attr = ' id="' . $GLOBALS['body_id'] . '"';
601
-	}
602
-
603
-	?>
550
+    /** This action is documented in wp-admin/admin-header.php */
551
+    do_action( 'admin_enqueue_scripts', 'media-upload-popup' );
552
+
553
+    /**
554
+     * Fires when admin styles enqueued for the legacy (pre-3.5.0) media upload popup are printed.
555
+     *
556
+     * @since 2.9.0
557
+     */
558
+    do_action( 'admin_print_styles-media-upload-popup' );  // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
559
+
560
+    /** This action is documented in wp-admin/admin-header.php */
561
+    do_action( 'admin_print_styles' );
562
+
563
+    /**
564
+     * Fires when admin scripts enqueued for the legacy (pre-3.5.0) media upload popup are printed.
565
+     *
566
+     * @since 2.9.0
567
+     */
568
+    do_action( 'admin_print_scripts-media-upload-popup' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
569
+
570
+    /** This action is documented in wp-admin/admin-header.php */
571
+    do_action( 'admin_print_scripts' );
572
+
573
+    /**
574
+     * Fires when scripts enqueued for the admin header for the legacy (pre-3.5.0)
575
+     * media upload popup are printed.
576
+     *
577
+     * @since 2.9.0
578
+     */
579
+    do_action( 'admin_head-media-upload-popup' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
580
+
581
+    /** This action is documented in wp-admin/admin-header.php */
582
+    do_action( 'admin_head' );
583
+
584
+    if ( is_string( $content_func ) ) {
585
+        /**
586
+         * Fires in the admin header for each specific form tab in the legacy
587
+         * (pre-3.5.0) media upload popup.
588
+         *
589
+         * The dynamic portion of the hook name, `$content_func`, refers to the form
590
+         * callback for the media upload type.
591
+         *
592
+         * @since 2.5.0
593
+         */
594
+        do_action( "admin_head_{$content_func}" );
595
+    }
596
+
597
+    $body_id_attr = '';
598
+
599
+    if ( isset( $GLOBALS['body_id'] ) ) {
600
+        $body_id_attr = ' id="' . $GLOBALS['body_id'] . '"';
601
+    }
602
+
603
+    ?>
604 604
 	</head>
605 605
 	<body<?php echo $body_id_attr; ?> class="wp-core-ui no-js">
606 606
 	<script type="text/javascript">
@@ -608,12 +608,12 @@  discard block
 block discarded – undo
608 608
 	</script>
609 609
 	<?php
610 610
 
611
-	call_user_func_array( $content_func, $args );
611
+    call_user_func_array( $content_func, $args );
612 612
 
613
-	/** This action is documented in wp-admin/admin-footer.php */
614
-	do_action( 'admin_print_footer_scripts' );
613
+    /** This action is documented in wp-admin/admin-footer.php */
614
+    do_action( 'admin_print_footer_scripts' );
615 615
 
616
-	?>
616
+    ?>
617 617
 	<script type="text/javascript">if(typeof wpOnload==='function')wpOnload();</script>
618 618
 	</body>
619 619
 	</html>
@@ -630,47 +630,47 @@  discard block
 block discarded – undo
630 630
  * @param string $editor_id
631 631
  */
632 632
 function media_buttons( $editor_id = 'content' ) {
633
-	static $instance = 0;
634
-	$instance++;
635
-
636
-	$post = get_post();
637
-
638
-	if ( ! $post && ! empty( $GLOBALS['post_ID'] ) ) {
639
-		$post = $GLOBALS['post_ID'];
640
-	}
641
-
642
-	wp_enqueue_media( array( 'post' => $post ) );
643
-
644
-	$img = '<span class="wp-media-buttons-icon"></span> ';
645
-
646
-	$id_attribute = 1 === $instance ? ' id="insert-media-button"' : '';
647
-
648
-	printf(
649
-		'<button type="button"%s class="button insert-media add_media" data-editor="%s">%s</button>',
650
-		$id_attribute,
651
-		esc_attr( $editor_id ),
652
-		$img . __( 'Add Media' )
653
-	);
654
-
655
-	/**
656
-	 * Filters the legacy (pre-3.5.0) media buttons.
657
-	 *
658
-	 * Use {@see 'media_buttons'} action instead.
659
-	 *
660
-	 * @since 2.5.0
661
-	 * @deprecated 3.5.0 Use {@see 'media_buttons'} action instead.
662
-	 *
663
-	 * @param string $string Media buttons context. Default empty.
664
-	 */
665
-	$legacy_filter = apply_filters_deprecated( 'media_buttons_context', array( '' ), '3.5.0', 'media_buttons' );
666
-
667
-	if ( $legacy_filter ) {
668
-		// #WP22559. Close <a> if a plugin started by closing <a> to open their own <a> tag.
669
-		if ( 0 === stripos( trim( $legacy_filter ), '</a>' ) ) {
670
-			$legacy_filter .= '</a>';
671
-		}
672
-		echo $legacy_filter;
673
-	}
633
+    static $instance = 0;
634
+    $instance++;
635
+
636
+    $post = get_post();
637
+
638
+    if ( ! $post && ! empty( $GLOBALS['post_ID'] ) ) {
639
+        $post = $GLOBALS['post_ID'];
640
+    }
641
+
642
+    wp_enqueue_media( array( 'post' => $post ) );
643
+
644
+    $img = '<span class="wp-media-buttons-icon"></span> ';
645
+
646
+    $id_attribute = 1 === $instance ? ' id="insert-media-button"' : '';
647
+
648
+    printf(
649
+        '<button type="button"%s class="button insert-media add_media" data-editor="%s">%s</button>',
650
+        $id_attribute,
651
+        esc_attr( $editor_id ),
652
+        $img . __( 'Add Media' )
653
+    );
654
+
655
+    /**
656
+     * Filters the legacy (pre-3.5.0) media buttons.
657
+     *
658
+     * Use {@see 'media_buttons'} action instead.
659
+     *
660
+     * @since 2.5.0
661
+     * @deprecated 3.5.0 Use {@see 'media_buttons'} action instead.
662
+     *
663
+     * @param string $string Media buttons context. Default empty.
664
+     */
665
+    $legacy_filter = apply_filters_deprecated( 'media_buttons_context', array( '' ), '3.5.0', 'media_buttons' );
666
+
667
+    if ( $legacy_filter ) {
668
+        // #WP22559. Close <a> if a plugin started by closing <a> to open their own <a> tag.
669
+        if ( 0 === stripos( trim( $legacy_filter ), '</a>' ) ) {
670
+            $legacy_filter .= '</a>';
671
+        }
672
+        echo $legacy_filter;
673
+    }
674 674
 }
675 675
 
676 676
 /**
@@ -681,40 +681,40 @@  discard block
 block discarded – undo
681 681
  * @return string
682 682
  */
683 683
 function get_upload_iframe_src( $type = null, $post_id = null, $tab = null ) {
684
-	global $post_ID;
685
-
686
-	if ( empty( $post_id ) ) {
687
-		$post_id = $post_ID;
688
-	}
689
-
690
-	$upload_iframe_src = add_query_arg( 'post_id', (int) $post_id, admin_url( 'media-upload.php' ) );
691
-
692
-	if ( $type && 'media' !== $type ) {
693
-		$upload_iframe_src = add_query_arg( 'type', $type, $upload_iframe_src );
694
-	}
695
-
696
-	if ( ! empty( $tab ) ) {
697
-		$upload_iframe_src = add_query_arg( 'tab', $tab, $upload_iframe_src );
698
-	}
699
-
700
-	/**
701
-	 * Filters the upload iframe source URL for a specific media type.
702
-	 *
703
-	 * The dynamic portion of the hook name, `$type`, refers to the type
704
-	 * of media uploaded.
705
-	 *
706
-	 * Possible hook names include:
707
-	 *
708
-	 *  - `image_upload_iframe_src`
709
-	 *  - `media_upload_iframe_src`
710
-	 *
711
-	 * @since 3.0.0
712
-	 *
713
-	 * @param string $upload_iframe_src The upload iframe source URL.
714
-	 */
715
-	$upload_iframe_src = apply_filters( "{$type}_upload_iframe_src", $upload_iframe_src );
716
-
717
-	return add_query_arg( 'TB_iframe', true, $upload_iframe_src );
684
+    global $post_ID;
685
+
686
+    if ( empty( $post_id ) ) {
687
+        $post_id = $post_ID;
688
+    }
689
+
690
+    $upload_iframe_src = add_query_arg( 'post_id', (int) $post_id, admin_url( 'media-upload.php' ) );
691
+
692
+    if ( $type && 'media' !== $type ) {
693
+        $upload_iframe_src = add_query_arg( 'type', $type, $upload_iframe_src );
694
+    }
695
+
696
+    if ( ! empty( $tab ) ) {
697
+        $upload_iframe_src = add_query_arg( 'tab', $tab, $upload_iframe_src );
698
+    }
699
+
700
+    /**
701
+     * Filters the upload iframe source URL for a specific media type.
702
+     *
703
+     * The dynamic portion of the hook name, `$type`, refers to the type
704
+     * of media uploaded.
705
+     *
706
+     * Possible hook names include:
707
+     *
708
+     *  - `image_upload_iframe_src`
709
+     *  - `media_upload_iframe_src`
710
+     *
711
+     * @since 3.0.0
712
+     *
713
+     * @param string $upload_iframe_src The upload iframe source URL.
714
+     */
715
+    $upload_iframe_src = apply_filters( "{$type}_upload_iframe_src", $upload_iframe_src );
716
+
717
+    return add_query_arg( 'TB_iframe', true, $upload_iframe_src );
718 718
 }
719 719
 
720 720
 /**
@@ -725,128 +725,128 @@  discard block
 block discarded – undo
725 725
  * @return null|array|void Array of error messages keyed by attachment ID, null or void on success.
726 726
  */
727 727
 function media_upload_form_handler() {
728
-	check_admin_referer( 'media-form' );
729
-
730
-	$errors = null;
731
-
732
-	if ( isset( $_POST['send'] ) ) {
733
-		$keys    = array_keys( $_POST['send'] );
734
-		$send_id = (int) reset( $keys );
735
-	}
736
-
737
-	if ( ! empty( $_POST['attachments'] ) ) {
738
-		foreach ( $_POST['attachments'] as $attachment_id => $attachment ) {
739
-			$post  = get_post( $attachment_id, ARRAY_A );
740
-			$_post = $post;
741
-
742
-			if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
743
-				continue;
744
-			}
745
-
746
-			if ( isset( $attachment['post_content'] ) ) {
747
-				$post['post_content'] = $attachment['post_content'];
748
-			}
749
-
750
-			if ( isset( $attachment['post_title'] ) ) {
751
-				$post['post_title'] = $attachment['post_title'];
752
-			}
753
-
754
-			if ( isset( $attachment['post_excerpt'] ) ) {
755
-				$post['post_excerpt'] = $attachment['post_excerpt'];
756
-			}
757
-
758
-			if ( isset( $attachment['menu_order'] ) ) {
759
-				$post['menu_order'] = $attachment['menu_order'];
760
-			}
761
-
762
-			if ( isset( $send_id ) && $attachment_id == $send_id ) {
763
-				if ( isset( $attachment['post_parent'] ) ) {
764
-					$post['post_parent'] = $attachment['post_parent'];
765
-				}
766
-			}
767
-
768
-			/**
769
-			 * Filters the attachment fields to be saved.
770
-			 *
771
-			 * @since 2.5.0
772
-			 *
773
-			 * @see wp_get_attachment_metadata()
774
-			 *
775
-			 * @param array $post       An array of post data.
776
-			 * @param array $attachment An array of attachment metadata.
777
-			 */
778
-			$post = apply_filters( 'attachment_fields_to_save', $post, $attachment );
779
-
780
-			if ( isset( $attachment['image_alt'] ) ) {
781
-				$image_alt = wp_unslash( $attachment['image_alt'] );
782
-
783
-				if ( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) !== $image_alt ) {
784
-					$image_alt = wp_strip_all_tags( $image_alt, true );
785
-
786
-					// update_post_meta() expects slashed.
787
-					update_post_meta( $attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
788
-				}
789
-			}
790
-
791
-			if ( isset( $post['errors'] ) ) {
792
-				$errors[ $attachment_id ] = $post['errors'];
793
-				unset( $post['errors'] );
794
-			}
795
-
796
-			if ( $post != $_post ) {
797
-				wp_update_post( $post );
798
-			}
799
-
800
-			foreach ( get_attachment_taxonomies( $post ) as $t ) {
801
-				if ( isset( $attachment[ $t ] ) ) {
802
-					wp_set_object_terms( $attachment_id, array_map( 'trim', preg_split( '/,+/', $attachment[ $t ] ) ), $t, false );
803
-				}
804
-			}
805
-		}
806
-	}
807
-
808
-	if ( isset( $_POST['insert-gallery'] ) || isset( $_POST['update-gallery'] ) ) {
809
-		?>
728
+    check_admin_referer( 'media-form' );
729
+
730
+    $errors = null;
731
+
732
+    if ( isset( $_POST['send'] ) ) {
733
+        $keys    = array_keys( $_POST['send'] );
734
+        $send_id = (int) reset( $keys );
735
+    }
736
+
737
+    if ( ! empty( $_POST['attachments'] ) ) {
738
+        foreach ( $_POST['attachments'] as $attachment_id => $attachment ) {
739
+            $post  = get_post( $attachment_id, ARRAY_A );
740
+            $_post = $post;
741
+
742
+            if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
743
+                continue;
744
+            }
745
+
746
+            if ( isset( $attachment['post_content'] ) ) {
747
+                $post['post_content'] = $attachment['post_content'];
748
+            }
749
+
750
+            if ( isset( $attachment['post_title'] ) ) {
751
+                $post['post_title'] = $attachment['post_title'];
752
+            }
753
+
754
+            if ( isset( $attachment['post_excerpt'] ) ) {
755
+                $post['post_excerpt'] = $attachment['post_excerpt'];
756
+            }
757
+
758
+            if ( isset( $attachment['menu_order'] ) ) {
759
+                $post['menu_order'] = $attachment['menu_order'];
760
+            }
761
+
762
+            if ( isset( $send_id ) && $attachment_id == $send_id ) {
763
+                if ( isset( $attachment['post_parent'] ) ) {
764
+                    $post['post_parent'] = $attachment['post_parent'];
765
+                }
766
+            }
767
+
768
+            /**
769
+             * Filters the attachment fields to be saved.
770
+             *
771
+             * @since 2.5.0
772
+             *
773
+             * @see wp_get_attachment_metadata()
774
+             *
775
+             * @param array $post       An array of post data.
776
+             * @param array $attachment An array of attachment metadata.
777
+             */
778
+            $post = apply_filters( 'attachment_fields_to_save', $post, $attachment );
779
+
780
+            if ( isset( $attachment['image_alt'] ) ) {
781
+                $image_alt = wp_unslash( $attachment['image_alt'] );
782
+
783
+                if ( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) !== $image_alt ) {
784
+                    $image_alt = wp_strip_all_tags( $image_alt, true );
785
+
786
+                    // update_post_meta() expects slashed.
787
+                    update_post_meta( $attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) );
788
+                }
789
+            }
790
+
791
+            if ( isset( $post['errors'] ) ) {
792
+                $errors[ $attachment_id ] = $post['errors'];
793
+                unset( $post['errors'] );
794
+            }
795
+
796
+            if ( $post != $_post ) {
797
+                wp_update_post( $post );
798
+            }
799
+
800
+            foreach ( get_attachment_taxonomies( $post ) as $t ) {
801
+                if ( isset( $attachment[ $t ] ) ) {
802
+                    wp_set_object_terms( $attachment_id, array_map( 'trim', preg_split( '/,+/', $attachment[ $t ] ) ), $t, false );
803
+                }
804
+            }
805
+        }
806
+    }
807
+
808
+    if ( isset( $_POST['insert-gallery'] ) || isset( $_POST['update-gallery'] ) ) {
809
+        ?>
810 810
 		<script type="text/javascript">
811 811
 		var win = window.dialogArguments || opener || parent || top;
812 812
 		win.tb_remove();
813 813
 		</script>
814 814
 		<?php
815 815
 
816
-		exit;
817
-	}
816
+        exit;
817
+    }
818 818
 
819
-	if ( isset( $send_id ) ) {
820
-		$attachment = wp_unslash( $_POST['attachments'][ $send_id ] );
821
-		$html       = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
819
+    if ( isset( $send_id ) ) {
820
+        $attachment = wp_unslash( $_POST['attachments'][ $send_id ] );
821
+        $html       = isset( $attachment['post_title'] ) ? $attachment['post_title'] : '';
822 822
 
823
-		if ( ! empty( $attachment['url'] ) ) {
824
-			$rel = '';
823
+        if ( ! empty( $attachment['url'] ) ) {
824
+            $rel = '';
825 825
 
826
-			if ( strpos( $attachment['url'], 'attachment_id' ) || get_attachment_link( $send_id ) == $attachment['url'] ) {
827
-				$rel = " rel='attachment wp-att-" . esc_attr( $send_id ) . "'";
828
-			}
826
+            if ( strpos( $attachment['url'], 'attachment_id' ) || get_attachment_link( $send_id ) == $attachment['url'] ) {
827
+                $rel = " rel='attachment wp-att-" . esc_attr( $send_id ) . "'";
828
+            }
829 829
 
830
-			$html = "<a href='{$attachment['url']}'$rel>$html</a>";
831
-		}
830
+            $html = "<a href='{$attachment['url']}'$rel>$html</a>";
831
+        }
832 832
 
833
-		/**
834
-		 * Filters the HTML markup for a media item sent to the editor.
835
-		 *
836
-		 * @since 2.5.0
837
-		 *
838
-		 * @see wp_get_attachment_metadata()
839
-		 *
840
-		 * @param string $html       HTML markup for a media item sent to the editor.
841
-		 * @param int    $send_id    The first key from the $_POST['send'] data.
842
-		 * @param array  $attachment Array of attachment metadata.
843
-		 */
844
-		$html = apply_filters( 'media_send_to_editor', $html, $send_id, $attachment );
845
-
846
-		return media_send_to_editor( $html );
847
-	}
833
+        /**
834
+         * Filters the HTML markup for a media item sent to the editor.
835
+         *
836
+         * @since 2.5.0
837
+         *
838
+         * @see wp_get_attachment_metadata()
839
+         *
840
+         * @param string $html       HTML markup for a media item sent to the editor.
841
+         * @param int    $send_id    The first key from the $_POST['send'] data.
842
+         * @param array  $attachment Array of attachment metadata.
843
+         */
844
+        $html = apply_filters( 'media_send_to_editor', $html, $send_id, $attachment );
848 845
 
849
-	return $errors;
846
+        return media_send_to_editor( $html );
847
+    }
848
+
849
+    return $errors;
850 850
 }
851 851
 
852 852
 /**
@@ -857,126 +857,126 @@  discard block
 block discarded – undo
857 857
  * @return null|string
858 858
  */
859 859
 function wp_media_upload_handler() {
860
-	$errors = array();
861
-	$id     = 0;
862
-
863
-	if ( isset( $_POST['html-upload'] ) && ! empty( $_FILES ) ) {
864
-		check_admin_referer( 'media-form' );
865
-		// Upload File button was clicked.
866
-		$id = media_handle_upload( 'async-upload', $_REQUEST['post_id'] );
867
-		unset( $_FILES );
868
-
869
-		if ( is_wp_error( $id ) ) {
870
-			$errors['upload_error'] = $id;
871
-			$id                     = false;
872
-		}
873
-	}
874
-
875
-	if ( ! empty( $_POST['insertonlybutton'] ) ) {
876
-		$src = $_POST['src'];
877
-
878
-		if ( ! empty( $src ) && ! strpos( $src, '://' ) ) {
879
-			$src = "http://$src";
880
-		}
881
-
882
-		if ( isset( $_POST['media_type'] ) && 'image' !== $_POST['media_type'] ) {
883
-			$title = esc_html( wp_unslash( $_POST['title'] ) );
884
-			if ( empty( $title ) ) {
885
-				$title = esc_html( wp_basename( $src ) );
886
-			}
887
-
888
-			if ( $title && $src ) {
889
-				$html = "<a href='" . esc_url( $src ) . "'>$title</a>";
890
-			}
891
-
892
-			$type = 'file';
893
-			$ext  = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src );
894
-
895
-			if ( $ext ) {
896
-				$ext_type = wp_ext2type( $ext );
897
-				if ( 'audio' === $ext_type || 'video' === $ext_type ) {
898
-					$type = $ext_type;
899
-				}
900
-			}
901
-
902
-			/**
903
-			 * Filters the URL sent to the editor for a specific media type.
904
-			 *
905
-			 * The dynamic portion of the hook name, `$type`, refers to the type
906
-			 * of media being sent.
907
-			 *
908
-			 * Possible hook names include:
909
-			 *
910
-			 *  - `audio_send_to_editor_url`
911
-			 *  - `file_send_to_editor_url`
912
-			 *  - `video_send_to_editor_url`
913
-			 *
914
-			 * @since 3.3.0
915
-			 *
916
-			 * @param string $html  HTML markup sent to the editor.
917
-			 * @param string $src   Media source URL.
918
-			 * @param string $title Media title.
919
-			 */
920
-			$html = apply_filters( "{$type}_send_to_editor_url", $html, esc_url_raw( $src ), $title );
921
-		} else {
922
-			$align = '';
923
-			$alt   = esc_attr( wp_unslash( $_POST['alt'] ) );
924
-
925
-			if ( isset( $_POST['align'] ) ) {
926
-				$align = esc_attr( wp_unslash( $_POST['align'] ) );
927
-				$class = " class='align$align'";
928
-			}
929
-
930
-			if ( ! empty( $src ) ) {
931
-				$html = "<img src='" . esc_url( $src ) . "' alt='$alt'$class />";
932
-			}
933
-
934
-			/**
935
-			 * Filters the image URL sent to the editor.
936
-			 *
937
-			 * @since 2.8.0
938
-			 *
939
-			 * @param string $html  HTML markup sent to the editor for an image.
940
-			 * @param string $src   Image source URL.
941
-			 * @param string $alt   Image alternate, or alt, text.
942
-			 * @param string $align The image alignment. Default 'alignnone'. Possible values include
943
-			 *                      'alignleft', 'aligncenter', 'alignright', 'alignnone'.
944
-			 */
945
-			$html = apply_filters( 'image_send_to_editor_url', $html, esc_url_raw( $src ), $alt, $align );
946
-		}
947
-
948
-		return media_send_to_editor( $html );
949
-	}
950
-
951
-	if ( isset( $_POST['save'] ) ) {
952
-		$errors['upload_notice'] = __( 'Saved.' );
953
-		wp_enqueue_script( 'admin-gallery' );
954
-
955
-		return wp_iframe( 'media_upload_gallery_form', $errors );
956
-
957
-	} elseif ( ! empty( $_POST ) ) {
958
-		$return = media_upload_form_handler();
959
-
960
-		if ( is_string( $return ) ) {
961
-			return $return;
962
-		}
963
-
964
-		if ( is_array( $return ) ) {
965
-			$errors = $return;
966
-		}
967
-	}
968
-
969
-	if ( isset( $_GET['tab'] ) && 'type_url' === $_GET['tab'] ) {
970
-		$type = 'image';
971
-
972
-		if ( isset( $_GET['type'] ) && in_array( $_GET['type'], array( 'video', 'audio', 'file' ), true ) ) {
973
-			$type = $_GET['type'];
974
-		}
975
-
976
-		return wp_iframe( 'media_upload_type_url_form', $type, $errors, $id );
977
-	}
978
-
979
-	return wp_iframe( 'media_upload_type_form', 'image', $errors, $id );
860
+    $errors = array();
861
+    $id     = 0;
862
+
863
+    if ( isset( $_POST['html-upload'] ) && ! empty( $_FILES ) ) {
864
+        check_admin_referer( 'media-form' );
865
+        // Upload File button was clicked.
866
+        $id = media_handle_upload( 'async-upload', $_REQUEST['post_id'] );
867
+        unset( $_FILES );
868
+
869
+        if ( is_wp_error( $id ) ) {
870
+            $errors['upload_error'] = $id;
871
+            $id                     = false;
872
+        }
873
+    }
874
+
875
+    if ( ! empty( $_POST['insertonlybutton'] ) ) {
876
+        $src = $_POST['src'];
877
+
878
+        if ( ! empty( $src ) && ! strpos( $src, '://' ) ) {
879
+            $src = "http://$src";
880
+        }
881
+
882
+        if ( isset( $_POST['media_type'] ) && 'image' !== $_POST['media_type'] ) {
883
+            $title = esc_html( wp_unslash( $_POST['title'] ) );
884
+            if ( empty( $title ) ) {
885
+                $title = esc_html( wp_basename( $src ) );
886
+            }
887
+
888
+            if ( $title && $src ) {
889
+                $html = "<a href='" . esc_url( $src ) . "'>$title</a>";
890
+            }
891
+
892
+            $type = 'file';
893
+            $ext  = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src );
894
+
895
+            if ( $ext ) {
896
+                $ext_type = wp_ext2type( $ext );
897
+                if ( 'audio' === $ext_type || 'video' === $ext_type ) {
898
+                    $type = $ext_type;
899
+                }
900
+            }
901
+
902
+            /**
903
+             * Filters the URL sent to the editor for a specific media type.
904
+             *
905
+             * The dynamic portion of the hook name, `$type`, refers to the type
906
+             * of media being sent.
907
+             *
908
+             * Possible hook names include:
909
+             *
910
+             *  - `audio_send_to_editor_url`
911
+             *  - `file_send_to_editor_url`
912
+             *  - `video_send_to_editor_url`
913
+             *
914
+             * @since 3.3.0
915
+             *
916
+             * @param string $html  HTML markup sent to the editor.
917
+             * @param string $src   Media source URL.
918
+             * @param string $title Media title.
919
+             */
920
+            $html = apply_filters( "{$type}_send_to_editor_url", $html, esc_url_raw( $src ), $title );
921
+        } else {
922
+            $align = '';
923
+            $alt   = esc_attr( wp_unslash( $_POST['alt'] ) );
924
+
925
+            if ( isset( $_POST['align'] ) ) {
926
+                $align = esc_attr( wp_unslash( $_POST['align'] ) );
927
+                $class = " class='align$align'";
928
+            }
929
+
930
+            if ( ! empty( $src ) ) {
931
+                $html = "<img src='" . esc_url( $src ) . "' alt='$alt'$class />";
932
+            }
933
+
934
+            /**
935
+             * Filters the image URL sent to the editor.
936
+             *
937
+             * @since 2.8.0
938
+             *
939
+             * @param string $html  HTML markup sent to the editor for an image.
940
+             * @param string $src   Image source URL.
941
+             * @param string $alt   Image alternate, or alt, text.
942
+             * @param string $align The image alignment. Default 'alignnone'. Possible values include
943
+             *                      'alignleft', 'aligncenter', 'alignright', 'alignnone'.
944
+             */
945
+            $html = apply_filters( 'image_send_to_editor_url', $html, esc_url_raw( $src ), $alt, $align );
946
+        }
947
+
948
+        return media_send_to_editor( $html );
949
+    }
950
+
951
+    if ( isset( $_POST['save'] ) ) {
952
+        $errors['upload_notice'] = __( 'Saved.' );
953
+        wp_enqueue_script( 'admin-gallery' );
954
+
955
+        return wp_iframe( 'media_upload_gallery_form', $errors );
956
+
957
+    } elseif ( ! empty( $_POST ) ) {
958
+        $return = media_upload_form_handler();
959
+
960
+        if ( is_string( $return ) ) {
961
+            return $return;
962
+        }
963
+
964
+        if ( is_array( $return ) ) {
965
+            $errors = $return;
966
+        }
967
+    }
968
+
969
+    if ( isset( $_GET['tab'] ) && 'type_url' === $_GET['tab'] ) {
970
+        $type = 'image';
971
+
972
+        if ( isset( $_GET['type'] ) && in_array( $_GET['type'], array( 'video', 'audio', 'file' ), true ) ) {
973
+            $type = $_GET['type'];
974
+        }
975
+
976
+        return wp_iframe( 'media_upload_type_url_form', $type, $errors, $id );
977
+    }
978
+
979
+    return wp_iframe( 'media_upload_type_form', 'image', $errors, $id );
980 980
 }
981 981
 
982 982
 /**
@@ -998,80 +998,80 @@  discard block
 block discarded – undo
998 998
  *                             on success, WP_Error object otherwise.
999 999
  */
1000 1000
 function media_sideload_image( $file, $post_id = 0, $desc = null, $return_type = 'html' ) {
1001
-	if ( ! empty( $file ) ) {
1002
-
1003
-		$allowed_extensions = array( 'jpg', 'jpeg', 'jpe', 'png', 'gif', 'webp' );
1004
-
1005
-		/**
1006
-		 * Filters the list of allowed file extensions when sideloading an image from a URL.
1007
-		 *
1008
-		 * The default allowed extensions are:
1009
-		 *
1010
-		 *  - `jpg`
1011
-		 *  - `jpeg`
1012
-		 *  - `jpe`
1013
-		 *  - `png`
1014
-		 *  - `gif`
1015
-		 *
1016
-		 * @since 5.6.0
1017
-		 *
1018
-		 * @param string[] $allowed_extensions Array of allowed file extensions.
1019
-		 * @param string   $file               The URL of the image to download.
1020
-		 */
1021
-		$allowed_extensions = apply_filters( 'image_sideload_extensions', $allowed_extensions, $file );
1022
-		$allowed_extensions = array_map( 'preg_quote', $allowed_extensions );
1023
-
1024
-		// Set variables for storage, fix file filename for query strings.
1025
-		preg_match( '/[^\?]+\.(' . implode( '|', $allowed_extensions ) . ')\b/i', $file, $matches );
1026
-
1027
-		if ( ! $matches ) {
1028
-			return new WP_Error( 'image_sideload_failed', __( 'Invalid image URL.' ) );
1029
-		}
1030
-
1031
-		$file_array         = array();
1032
-		$file_array['name'] = wp_basename( $matches[0] );
1033
-
1034
-		// Download file to temp location.
1035
-		$file_array['tmp_name'] = download_url( $file );
1036
-
1037
-		// If error storing temporarily, return the error.
1038
-		if ( is_wp_error( $file_array['tmp_name'] ) ) {
1039
-			return $file_array['tmp_name'];
1040
-		}
1041
-
1042
-		// Do the validation and storage stuff.
1043
-		$id = media_handle_sideload( $file_array, $post_id, $desc );
1044
-
1045
-		// If error storing permanently, unlink.
1046
-		if ( is_wp_error( $id ) ) {
1047
-			@unlink( $file_array['tmp_name'] );
1048
-			return $id;
1049
-		}
1050
-
1051
-		// Store the original attachment source in meta.
1052
-		add_post_meta( $id, '_source_url', $file );
1053
-
1054
-		// If attachment ID was requested, return it.
1055
-		if ( 'id' === $return_type ) {
1056
-			return $id;
1057
-		}
1058
-
1059
-		$src = wp_get_attachment_url( $id );
1060
-	}
1061
-
1062
-	// Finally, check to make sure the file has been saved, then return the HTML.
1063
-	if ( ! empty( $src ) ) {
1064
-		if ( 'src' === $return_type ) {
1065
-			return $src;
1066
-		}
1067
-
1068
-		$alt  = isset( $desc ) ? esc_attr( $desc ) : '';
1069
-		$html = "<img src='$src' alt='$alt' />";
1070
-
1071
-		return $html;
1072
-	} else {
1073
-		return new WP_Error( 'image_sideload_failed' );
1074
-	}
1001
+    if ( ! empty( $file ) ) {
1002
+
1003
+        $allowed_extensions = array( 'jpg', 'jpeg', 'jpe', 'png', 'gif', 'webp' );
1004
+
1005
+        /**
1006
+         * Filters the list of allowed file extensions when sideloading an image from a URL.
1007
+         *
1008
+         * The default allowed extensions are:
1009
+         *
1010
+         *  - `jpg`
1011
+         *  - `jpeg`
1012
+         *  - `jpe`
1013
+         *  - `png`
1014
+         *  - `gif`
1015
+         *
1016
+         * @since 5.6.0
1017
+         *
1018
+         * @param string[] $allowed_extensions Array of allowed file extensions.
1019
+         * @param string   $file               The URL of the image to download.
1020
+         */
1021
+        $allowed_extensions = apply_filters( 'image_sideload_extensions', $allowed_extensions, $file );
1022
+        $allowed_extensions = array_map( 'preg_quote', $allowed_extensions );
1023
+
1024
+        // Set variables for storage, fix file filename for query strings.
1025
+        preg_match( '/[^\?]+\.(' . implode( '|', $allowed_extensions ) . ')\b/i', $file, $matches );
1026
+
1027
+        if ( ! $matches ) {
1028
+            return new WP_Error( 'image_sideload_failed', __( 'Invalid image URL.' ) );
1029
+        }
1030
+
1031
+        $file_array         = array();
1032
+        $file_array['name'] = wp_basename( $matches[0] );
1033
+
1034
+        // Download file to temp location.
1035
+        $file_array['tmp_name'] = download_url( $file );
1036
+
1037
+        // If error storing temporarily, return the error.
1038
+        if ( is_wp_error( $file_array['tmp_name'] ) ) {
1039
+            return $file_array['tmp_name'];
1040
+        }
1041
+
1042
+        // Do the validation and storage stuff.
1043
+        $id = media_handle_sideload( $file_array, $post_id, $desc );
1044
+
1045
+        // If error storing permanently, unlink.
1046
+        if ( is_wp_error( $id ) ) {
1047
+            @unlink( $file_array['tmp_name'] );
1048
+            return $id;
1049
+        }
1050
+
1051
+        // Store the original attachment source in meta.
1052
+        add_post_meta( $id, '_source_url', $file );
1053
+
1054
+        // If attachment ID was requested, return it.
1055
+        if ( 'id' === $return_type ) {
1056
+            return $id;
1057
+        }
1058
+
1059
+        $src = wp_get_attachment_url( $id );
1060
+    }
1061
+
1062
+    // Finally, check to make sure the file has been saved, then return the HTML.
1063
+    if ( ! empty( $src ) ) {
1064
+        if ( 'src' === $return_type ) {
1065
+            return $src;
1066
+        }
1067
+
1068
+        $alt  = isset( $desc ) ? esc_attr( $desc ) : '';
1069
+        $html = "<img src='$src' alt='$alt' />";
1070
+
1071
+        return $html;
1072
+    } else {
1073
+        return new WP_Error( 'image_sideload_failed' );
1074
+    }
1075 1075
 }
1076 1076
 
1077 1077
 /**
@@ -1082,22 +1082,22 @@  discard block
 block discarded – undo
1082 1082
  * @return string|null
1083 1083
  */
1084 1084
 function media_upload_gallery() {
1085
-	$errors = array();
1085
+    $errors = array();
1086 1086
 
1087
-	if ( ! empty( $_POST ) ) {
1088
-		$return = media_upload_form_handler();
1087
+    if ( ! empty( $_POST ) ) {
1088
+        $return = media_upload_form_handler();
1089 1089
 
1090
-		if ( is_string( $return ) ) {
1091
-			return $return;
1092
-		}
1090
+        if ( is_string( $return ) ) {
1091
+            return $return;
1092
+        }
1093 1093
 
1094
-		if ( is_array( $return ) ) {
1095
-			$errors = $return;
1096
-		}
1097
-	}
1094
+        if ( is_array( $return ) ) {
1095
+            $errors = $return;
1096
+        }
1097
+    }
1098 1098
 
1099
-	wp_enqueue_script( 'admin-gallery' );
1100
-	return wp_iframe( 'media_upload_gallery_form', $errors );
1099
+    wp_enqueue_script( 'admin-gallery' );
1100
+    return wp_iframe( 'media_upload_gallery_form', $errors );
1101 1101
 }
1102 1102
 
1103 1103
 /**
@@ -1108,20 +1108,20 @@  discard block
 block discarded – undo
1108 1108
  * @return string|null
1109 1109
  */
1110 1110
 function media_upload_library() {
1111
-	$errors = array();
1111
+    $errors = array();
1112 1112
 
1113
-	if ( ! empty( $_POST ) ) {
1114
-		$return = media_upload_form_handler();
1113
+    if ( ! empty( $_POST ) ) {
1114
+        $return = media_upload_form_handler();
1115 1115
 
1116
-		if ( is_string( $return ) ) {
1117
-			return $return;
1118
-		}
1119
-		if ( is_array( $return ) ) {
1120
-			$errors = $return;
1121
-		}
1122
-	}
1116
+        if ( is_string( $return ) ) {
1117
+            return $return;
1118
+        }
1119
+        if ( is_array( $return ) ) {
1120
+            $errors = $return;
1121
+        }
1122
+    }
1123 1123
 
1124
-	return wp_iframe( 'media_upload_library_form', $errors );
1124
+    return wp_iframe( 'media_upload_library_form', $errors );
1125 1125
 }
1126 1126
 
1127 1127
 /**
@@ -1135,31 +1135,31 @@  discard block
 block discarded – undo
1135 1135
  */
1136 1136
 function image_align_input_fields( $post, $checked = '' ) {
1137 1137
 
1138
-	if ( empty( $checked ) ) {
1139
-		$checked = get_user_setting( 'align', 'none' );
1140
-	}
1138
+    if ( empty( $checked ) ) {
1139
+        $checked = get_user_setting( 'align', 'none' );
1140
+    }
1141 1141
 
1142
-	$alignments = array(
1143
-		'none'   => __( 'None' ),
1144
-		'left'   => __( 'Left' ),
1145
-		'center' => __( 'Center' ),
1146
-		'right'  => __( 'Right' ),
1147
-	);
1142
+    $alignments = array(
1143
+        'none'   => __( 'None' ),
1144
+        'left'   => __( 'Left' ),
1145
+        'center' => __( 'Center' ),
1146
+        'right'  => __( 'Right' ),
1147
+    );
1148 1148
 
1149
-	if ( ! array_key_exists( (string) $checked, $alignments ) ) {
1150
-		$checked = 'none';
1151
-	}
1149
+    if ( ! array_key_exists( (string) $checked, $alignments ) ) {
1150
+        $checked = 'none';
1151
+    }
1152 1152
 
1153
-	$out = array();
1153
+    $out = array();
1154 1154
 
1155
-	foreach ( $alignments as $name => $label ) {
1156
-		$name  = esc_attr( $name );
1157
-		$out[] = "<input type='radio' name='attachments[{$post->ID}][align]' id='image-align-{$name}-{$post->ID}' value='$name'" .
1158
-			( $checked == $name ? " checked='checked'" : '' ) .
1159
-			" /><label for='image-align-{$name}-{$post->ID}' class='align image-align-{$name}-label'>$label</label>";
1160
-	}
1155
+    foreach ( $alignments as $name => $label ) {
1156
+        $name  = esc_attr( $name );
1157
+        $out[] = "<input type='radio' name='attachments[{$post->ID}][align]' id='image-align-{$name}-{$post->ID}' value='$name'" .
1158
+            ( $checked == $name ? " checked='checked'" : '' ) .
1159
+            " /><label for='image-align-{$name}-{$post->ID}' class='align image-align-{$name}-label'>$label</label>";
1160
+    }
1161 1161
 
1162
-	return implode( "\n", $out );
1162
+    return implode( "\n", $out );
1163 1163
 }
1164 1164
 
1165 1165
 /**
@@ -1172,72 +1172,72 @@  discard block
 block discarded – undo
1172 1172
  * @return array
1173 1173
  */
1174 1174
 function image_size_input_fields( $post, $check = '' ) {
1175
-	/**
1176
-	 * Filters the names and labels of the default image sizes.
1177
-	 *
1178
-	 * @since 3.3.0
1179
-	 *
1180
-	 * @param string[] $size_names Array of image size labels keyed by their name. Default values
1181
-	 *                             include 'Thumbnail', 'Medium', 'Large', and 'Full Size'.
1182
-	 */
1183
-	$size_names = apply_filters(
1184
-		'image_size_names_choose',
1185
-		array(
1186
-			'thumbnail' => __( 'Thumbnail' ),
1187
-			'medium'    => __( 'Medium' ),
1188
-			'large'     => __( 'Large' ),
1189
-			'full'      => __( 'Full Size' ),
1190
-		)
1191
-	);
1192
-
1193
-	if ( empty( $check ) ) {
1194
-		$check = get_user_setting( 'imgsize', 'medium' );
1195
-	}
1196
-
1197
-	$out = array();
1198
-
1199
-	foreach ( $size_names as $size => $label ) {
1200
-		$downsize = image_downsize( $post->ID, $size );
1201
-		$checked  = '';
1202
-
1203
-		// Is this size selectable?
1204
-		$enabled = ( $downsize[3] || 'full' === $size );
1205
-		$css_id  = "image-size-{$size}-{$post->ID}";
1206
-
1207
-		// If this size is the default but that's not available, don't select it.
1208
-		if ( $size == $check ) {
1209
-			if ( $enabled ) {
1210
-				$checked = " checked='checked'";
1211
-			} else {
1212
-				$check = '';
1213
-			}
1214
-		} elseif ( ! $check && $enabled && 'thumbnail' !== $size ) {
1215
-			/*
1175
+    /**
1176
+     * Filters the names and labels of the default image sizes.
1177
+     *
1178
+     * @since 3.3.0
1179
+     *
1180
+     * @param string[] $size_names Array of image size labels keyed by their name. Default values
1181
+     *                             include 'Thumbnail', 'Medium', 'Large', and 'Full Size'.
1182
+     */
1183
+    $size_names = apply_filters(
1184
+        'image_size_names_choose',
1185
+        array(
1186
+            'thumbnail' => __( 'Thumbnail' ),
1187
+            'medium'    => __( 'Medium' ),
1188
+            'large'     => __( 'Large' ),
1189
+            'full'      => __( 'Full Size' ),
1190
+        )
1191
+    );
1192
+
1193
+    if ( empty( $check ) ) {
1194
+        $check = get_user_setting( 'imgsize', 'medium' );
1195
+    }
1196
+
1197
+    $out = array();
1198
+
1199
+    foreach ( $size_names as $size => $label ) {
1200
+        $downsize = image_downsize( $post->ID, $size );
1201
+        $checked  = '';
1202
+
1203
+        // Is this size selectable?
1204
+        $enabled = ( $downsize[3] || 'full' === $size );
1205
+        $css_id  = "image-size-{$size}-{$post->ID}";
1206
+
1207
+        // If this size is the default but that's not available, don't select it.
1208
+        if ( $size == $check ) {
1209
+            if ( $enabled ) {
1210
+                $checked = " checked='checked'";
1211
+            } else {
1212
+                $check = '';
1213
+            }
1214
+        } elseif ( ! $check && $enabled && 'thumbnail' !== $size ) {
1215
+            /*
1216 1216
 			 * If $check is not enabled, default to the first available size
1217 1217
 			 * that's bigger than a thumbnail.
1218 1218
 			 */
1219
-			$check   = $size;
1220
-			$checked = " checked='checked'";
1221
-		}
1219
+            $check   = $size;
1220
+            $checked = " checked='checked'";
1221
+        }
1222 1222
 
1223
-		$html = "<div class='image-size-item'><input type='radio' " . disabled( $enabled, false, false ) . "name='attachments[$post->ID][image-size]' id='{$css_id}' value='{$size}'$checked />";
1223
+        $html = "<div class='image-size-item'><input type='radio' " . disabled( $enabled, false, false ) . "name='attachments[$post->ID][image-size]' id='{$css_id}' value='{$size}'$checked />";
1224 1224
 
1225
-		$html .= "<label for='{$css_id}'>$label</label>";
1225
+        $html .= "<label for='{$css_id}'>$label</label>";
1226 1226
 
1227
-		// Only show the dimensions if that choice is available.
1228
-		if ( $enabled ) {
1229
-			$html .= " <label for='{$css_id}' class='help'>" . sprintf( '(%d&nbsp;&times;&nbsp;%d)', $downsize[1], $downsize[2] ) . '</label>';
1230
-		}
1231
-		$html .= '</div>';
1227
+        // Only show the dimensions if that choice is available.
1228
+        if ( $enabled ) {
1229
+            $html .= " <label for='{$css_id}' class='help'>" . sprintf( '(%d&nbsp;&times;&nbsp;%d)', $downsize[1], $downsize[2] ) . '</label>';
1230
+        }
1231
+        $html .= '</div>';
1232 1232
 
1233
-		$out[] = $html;
1234
-	}
1233
+        $out[] = $html;
1234
+    }
1235 1235
 
1236
-	return array(
1237
-		'label' => __( 'Size' ),
1238
-		'input' => 'html',
1239
-		'html'  => implode( "\n", $out ),
1240
-	);
1236
+    return array(
1237
+        'label' => __( 'Size' ),
1238
+        'input' => 'html',
1239
+        'html'  => implode( "\n", $out ),
1240
+    );
1241 1241
 }
1242 1242
 
1243 1243
 /**
@@ -1251,22 +1251,22 @@  discard block
 block discarded – undo
1251 1251
  */
1252 1252
 function image_link_input_fields( $post, $url_type = '' ) {
1253 1253
 
1254
-	$file = wp_get_attachment_url( $post->ID );
1255
-	$link = get_attachment_link( $post->ID );
1254
+    $file = wp_get_attachment_url( $post->ID );
1255
+    $link = get_attachment_link( $post->ID );
1256 1256
 
1257
-	if ( empty( $url_type ) ) {
1258
-		$url_type = get_user_setting( 'urlbutton', 'post' );
1259
-	}
1257
+    if ( empty( $url_type ) ) {
1258
+        $url_type = get_user_setting( 'urlbutton', 'post' );
1259
+    }
1260 1260
 
1261
-	$url = '';
1261
+    $url = '';
1262 1262
 
1263
-	if ( 'file' === $url_type ) {
1264
-		$url = $file;
1265
-	} elseif ( 'post' === $url_type ) {
1266
-		$url = $link;
1267
-	}
1263
+    if ( 'file' === $url_type ) {
1264
+        $url = $file;
1265
+    } elseif ( 'post' === $url_type ) {
1266
+        $url = $link;
1267
+    }
1268 1268
 
1269
-	return "
1269
+    return "
1270 1270
 	<input type='text' class='text urlfield' name='attachments[$post->ID][url]' value='" . esc_attr( $url ) . "' /><br />
1271 1271
 	<button type='button' class='button urlnone' data-link-url=''>" . __( 'None' ) . "</button>
1272 1272
 	<button type='button' class='button urlfile' data-link-url='" . esc_attr( $file ) . "'>" . __( 'File URL' ) . "</button>
@@ -1283,10 +1283,10 @@  discard block
 block discarded – undo
1283 1283
  * @return string HTML markup for the textarea element.
1284 1284
  */
1285 1285
 function wp_caption_input_textarea( $edit_post ) {
1286
-	// Post data is already escaped.
1287
-	$name = "attachments[{$edit_post->ID}][post_excerpt]";
1286
+    // Post data is already escaped.
1287
+    $name = "attachments[{$edit_post->ID}][post_excerpt]";
1288 1288
 
1289
-	return '<textarea name="' . $name . '" id="' . $name . '">' . $edit_post->post_excerpt . '</textarea>';
1289
+    return '<textarea name="' . $name . '" id="' . $name . '">' . $edit_post->post_excerpt . '</textarea>';
1290 1290
 }
1291 1291
 
1292 1292
 /**
@@ -1299,7 +1299,7 @@  discard block
 block discarded – undo
1299 1299
  * @return array
1300 1300
  */
1301 1301
 function image_attachment_fields_to_edit( $form_fields, $post ) {
1302
-	return $form_fields;
1302
+    return $form_fields;
1303 1303
 }
1304 1304
 
1305 1305
 /**
@@ -1312,8 +1312,8 @@  discard block
 block discarded – undo
1312 1312
  * @return array Filtered attachment form fields.
1313 1313
  */
1314 1314
 function media_single_attachment_fields_to_edit( $form_fields, $post ) {
1315
-	unset( $form_fields['url'], $form_fields['align'], $form_fields['image-size'] );
1316
-	return $form_fields;
1315
+    unset( $form_fields['url'], $form_fields['align'], $form_fields['image-size'] );
1316
+    return $form_fields;
1317 1317
 }
1318 1318
 
1319 1319
 /**
@@ -1326,8 +1326,8 @@  discard block
 block discarded – undo
1326 1326
  * @return array Filtered attachment form fields.
1327 1327
  */
1328 1328
 function media_post_single_attachment_fields_to_edit( $form_fields, $post ) {
1329
-	unset( $form_fields['image_url'] );
1330
-	return $form_fields;
1329
+    unset( $form_fields['image_url'] );
1330
+    return $form_fields;
1331 1331
 }
1332 1332
 
1333 1333
 /**
@@ -1341,19 +1341,19 @@  discard block
 block discarded – undo
1341 1341
  * @return string
1342 1342
  */
1343 1343
 function image_media_send_to_editor( $html, $attachment_id, $attachment ) {
1344
-	$post = get_post( $attachment_id );
1344
+    $post = get_post( $attachment_id );
1345 1345
 
1346
-	if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
1347
-		$url   = $attachment['url'];
1348
-		$align = ! empty( $attachment['align'] ) ? $attachment['align'] : 'none';
1349
-		$size  = ! empty( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
1350
-		$alt   = ! empty( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
1351
-		$rel   = ( strpos( $url, 'attachment_id' ) || get_attachment_link( $attachment_id ) === $url );
1346
+    if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
1347
+        $url   = $attachment['url'];
1348
+        $align = ! empty( $attachment['align'] ) ? $attachment['align'] : 'none';
1349
+        $size  = ! empty( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
1350
+        $alt   = ! empty( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
1351
+        $rel   = ( strpos( $url, 'attachment_id' ) || get_attachment_link( $attachment_id ) === $url );
1352 1352
 
1353
-		return get_image_send_to_editor( $attachment_id, $attachment['post_excerpt'], $attachment['post_title'], $align, $url, $rel, $size, $alt );
1354
-	}
1353
+        return get_image_send_to_editor( $attachment_id, $attachment['post_excerpt'], $attachment['post_title'], $align, $url, $rel, $size, $alt );
1354
+    }
1355 1355
 
1356
-	return $html;
1356
+    return $html;
1357 1357
 }
1358 1358
 
1359 1359
 /**
@@ -1366,132 +1366,132 @@  discard block
 block discarded – undo
1366 1366
  * @return array
1367 1367
  */
1368 1368
 function get_attachment_fields_to_edit( $post, $errors = null ) {
1369
-	if ( is_int( $post ) ) {
1370
-		$post = get_post( $post );
1371
-	}
1372
-
1373
-	if ( is_array( $post ) ) {
1374
-		$post = new WP_Post( (object) $post );
1375
-	}
1376
-
1377
-	$image_url = wp_get_attachment_url( $post->ID );
1378
-
1379
-	$edit_post = sanitize_post( $post, 'edit' );
1380
-
1381
-	$form_fields = array(
1382
-		'post_title'   => array(
1383
-			'label' => __( 'Title' ),
1384
-			'value' => $edit_post->post_title,
1385
-		),
1386
-		'image_alt'    => array(),
1387
-		'post_excerpt' => array(
1388
-			'label' => __( 'Caption' ),
1389
-			'input' => 'html',
1390
-			'html'  => wp_caption_input_textarea( $edit_post ),
1391
-		),
1392
-		'post_content' => array(
1393
-			'label' => __( 'Description' ),
1394
-			'value' => $edit_post->post_content,
1395
-			'input' => 'textarea',
1396
-		),
1397
-		'url'          => array(
1398
-			'label' => __( 'Link URL' ),
1399
-			'input' => 'html',
1400
-			'html'  => image_link_input_fields( $post, get_option( 'image_default_link_type' ) ),
1401
-			'helps' => __( 'Enter a link URL or click above for presets.' ),
1402
-		),
1403
-		'menu_order'   => array(
1404
-			'label' => __( 'Order' ),
1405
-			'value' => $edit_post->menu_order,
1406
-		),
1407
-		'image_url'    => array(
1408
-			'label' => __( 'File URL' ),
1409
-			'input' => 'html',
1410
-			'html'  => "<input type='text' class='text urlfield' readonly='readonly' name='attachments[$post->ID][url]' value='" . esc_attr( $image_url ) . "' /><br />",
1411
-			'value' => wp_get_attachment_url( $post->ID ),
1412
-			'helps' => __( 'Location of the uploaded file.' ),
1413
-		),
1414
-	);
1415
-
1416
-	foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
1417
-		$t = (array) get_taxonomy( $taxonomy );
1418
-
1419
-		if ( ! $t['public'] || ! $t['show_ui'] ) {
1420
-			continue;
1421
-		}
1422
-
1423
-		if ( empty( $t['label'] ) ) {
1424
-			$t['label'] = $taxonomy;
1425
-		}
1426
-
1427
-		if ( empty( $t['args'] ) ) {
1428
-			$t['args'] = array();
1429
-		}
1430
-
1431
-		$terms = get_object_term_cache( $post->ID, $taxonomy );
1432
-
1433
-		if ( false === $terms ) {
1434
-			$terms = wp_get_object_terms( $post->ID, $taxonomy, $t['args'] );
1435
-		}
1436
-
1437
-		$values = array();
1438
-
1439
-		foreach ( $terms as $term ) {
1440
-			$values[] = $term->slug;
1441
-		}
1442
-
1443
-		$t['value'] = implode( ', ', $values );
1444
-
1445
-		$form_fields[ $taxonomy ] = $t;
1446
-	}
1447
-
1448
-	/*
1369
+    if ( is_int( $post ) ) {
1370
+        $post = get_post( $post );
1371
+    }
1372
+
1373
+    if ( is_array( $post ) ) {
1374
+        $post = new WP_Post( (object) $post );
1375
+    }
1376
+
1377
+    $image_url = wp_get_attachment_url( $post->ID );
1378
+
1379
+    $edit_post = sanitize_post( $post, 'edit' );
1380
+
1381
+    $form_fields = array(
1382
+        'post_title'   => array(
1383
+            'label' => __( 'Title' ),
1384
+            'value' => $edit_post->post_title,
1385
+        ),
1386
+        'image_alt'    => array(),
1387
+        'post_excerpt' => array(
1388
+            'label' => __( 'Caption' ),
1389
+            'input' => 'html',
1390
+            'html'  => wp_caption_input_textarea( $edit_post ),
1391
+        ),
1392
+        'post_content' => array(
1393
+            'label' => __( 'Description' ),
1394
+            'value' => $edit_post->post_content,
1395
+            'input' => 'textarea',
1396
+        ),
1397
+        'url'          => array(
1398
+            'label' => __( 'Link URL' ),
1399
+            'input' => 'html',
1400
+            'html'  => image_link_input_fields( $post, get_option( 'image_default_link_type' ) ),
1401
+            'helps' => __( 'Enter a link URL or click above for presets.' ),
1402
+        ),
1403
+        'menu_order'   => array(
1404
+            'label' => __( 'Order' ),
1405
+            'value' => $edit_post->menu_order,
1406
+        ),
1407
+        'image_url'    => array(
1408
+            'label' => __( 'File URL' ),
1409
+            'input' => 'html',
1410
+            'html'  => "<input type='text' class='text urlfield' readonly='readonly' name='attachments[$post->ID][url]' value='" . esc_attr( $image_url ) . "' /><br />",
1411
+            'value' => wp_get_attachment_url( $post->ID ),
1412
+            'helps' => __( 'Location of the uploaded file.' ),
1413
+        ),
1414
+    );
1415
+
1416
+    foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
1417
+        $t = (array) get_taxonomy( $taxonomy );
1418
+
1419
+        if ( ! $t['public'] || ! $t['show_ui'] ) {
1420
+            continue;
1421
+        }
1422
+
1423
+        if ( empty( $t['label'] ) ) {
1424
+            $t['label'] = $taxonomy;
1425
+        }
1426
+
1427
+        if ( empty( $t['args'] ) ) {
1428
+            $t['args'] = array();
1429
+        }
1430
+
1431
+        $terms = get_object_term_cache( $post->ID, $taxonomy );
1432
+
1433
+        if ( false === $terms ) {
1434
+            $terms = wp_get_object_terms( $post->ID, $taxonomy, $t['args'] );
1435
+        }
1436
+
1437
+        $values = array();
1438
+
1439
+        foreach ( $terms as $term ) {
1440
+            $values[] = $term->slug;
1441
+        }
1442
+
1443
+        $t['value'] = implode( ', ', $values );
1444
+
1445
+        $form_fields[ $taxonomy ] = $t;
1446
+    }
1447
+
1448
+    /*
1449 1449
 	 * Merge default fields with their errors, so any key passed with the error
1450 1450
 	 * (e.g. 'error', 'helps', 'value') will replace the default.
1451 1451
 	 * The recursive merge is easily traversed with array casting:
1452 1452
 	 * foreach ( (array) $things as $thing )
1453 1453
 	 */
1454
-	$form_fields = array_merge_recursive( $form_fields, (array) $errors );
1455
-
1456
-	// This was formerly in image_attachment_fields_to_edit().
1457
-	if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
1458
-		$alt = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
1459
-
1460
-		if ( empty( $alt ) ) {
1461
-			$alt = '';
1462
-		}
1463
-
1464
-		$form_fields['post_title']['required'] = true;
1465
-
1466
-		$form_fields['image_alt'] = array(
1467
-			'value' => $alt,
1468
-			'label' => __( 'Alternative Text' ),
1469
-			'helps' => __( 'Alt text for the image, e.g. &#8220;The Mona Lisa&#8221;' ),
1470
-		);
1471
-
1472
-		$form_fields['align'] = array(
1473
-			'label' => __( 'Alignment' ),
1474
-			'input' => 'html',
1475
-			'html'  => image_align_input_fields( $post, get_option( 'image_default_align' ) ),
1476
-		);
1477
-
1478
-		$form_fields['image-size'] = image_size_input_fields( $post, get_option( 'image_default_size', 'medium' ) );
1479
-
1480
-	} else {
1481
-		unset( $form_fields['image_alt'] );
1482
-	}
1483
-
1484
-	/**
1485
-	 * Filters the attachment fields to edit.
1486
-	 *
1487
-	 * @since 2.5.0
1488
-	 *
1489
-	 * @param array   $form_fields An array of attachment form fields.
1490
-	 * @param WP_Post $post        The WP_Post attachment object.
1491
-	 */
1492
-	$form_fields = apply_filters( 'attachment_fields_to_edit', $form_fields, $post );
1493
-
1494
-	return $form_fields;
1454
+    $form_fields = array_merge_recursive( $form_fields, (array) $errors );
1455
+
1456
+    // This was formerly in image_attachment_fields_to_edit().
1457
+    if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
1458
+        $alt = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
1459
+
1460
+        if ( empty( $alt ) ) {
1461
+            $alt = '';
1462
+        }
1463
+
1464
+        $form_fields['post_title']['required'] = true;
1465
+
1466
+        $form_fields['image_alt'] = array(
1467
+            'value' => $alt,
1468
+            'label' => __( 'Alternative Text' ),
1469
+            'helps' => __( 'Alt text for the image, e.g. &#8220;The Mona Lisa&#8221;' ),
1470
+        );
1471
+
1472
+        $form_fields['align'] = array(
1473
+            'label' => __( 'Alignment' ),
1474
+            'input' => 'html',
1475
+            'html'  => image_align_input_fields( $post, get_option( 'image_default_align' ) ),
1476
+        );
1477
+
1478
+        $form_fields['image-size'] = image_size_input_fields( $post, get_option( 'image_default_size', 'medium' ) );
1479
+
1480
+    } else {
1481
+        unset( $form_fields['image_alt'] );
1482
+    }
1483
+
1484
+    /**
1485
+     * Filters the attachment fields to edit.
1486
+     *
1487
+     * @since 2.5.0
1488
+     *
1489
+     * @param array   $form_fields An array of attachment form fields.
1490
+     * @param WP_Post $post        The WP_Post attachment object.
1491
+     */
1492
+    $form_fields = apply_filters( 'attachment_fields_to_edit', $form_fields, $post );
1493
+
1494
+    return $form_fields;
1495 1495
 }
1496 1496
 
1497 1497
 /**
@@ -1510,45 +1510,45 @@  discard block
 block discarded – undo
1510 1510
  * @return string HTML content for media items of post gallery.
1511 1511
  */
1512 1512
 function get_media_items( $post_id, $errors ) {
1513
-	$attachments = array();
1514
-
1515
-	if ( $post_id ) {
1516
-		$post = get_post( $post_id );
1517
-
1518
-		if ( $post && 'attachment' === $post->post_type ) {
1519
-			$attachments = array( $post->ID => $post );
1520
-		} else {
1521
-			$attachments = get_children(
1522
-				array(
1523
-					'post_parent' => $post_id,
1524
-					'post_type'   => 'attachment',
1525
-					'orderby'     => 'menu_order ASC, ID',
1526
-					'order'       => 'DESC',
1527
-				)
1528
-			);
1529
-		}
1530
-	} else {
1531
-		if ( is_array( $GLOBALS['wp_the_query']->posts ) ) {
1532
-			foreach ( $GLOBALS['wp_the_query']->posts as $attachment ) {
1533
-				$attachments[ $attachment->ID ] = $attachment;
1534
-			}
1535
-		}
1536
-	}
1537
-
1538
-	$output = '';
1539
-	foreach ( (array) $attachments as $id => $attachment ) {
1540
-		if ( 'trash' === $attachment->post_status ) {
1541
-			continue;
1542
-		}
1543
-
1544
-		$item = get_media_item( $id, array( 'errors' => isset( $errors[ $id ] ) ? $errors[ $id ] : null ) );
1545
-
1546
-		if ( $item ) {
1547
-			$output .= "\n<div id='media-item-$id' class='media-item child-of-$attachment->post_parent preloaded'><div class='progress hidden'><div class='bar'></div></div><div id='media-upload-error-$id' class='hidden'></div><div class='filename hidden'></div>$item\n</div>";
1548
-		}
1549
-	}
1550
-
1551
-	return $output;
1513
+    $attachments = array();
1514
+
1515
+    if ( $post_id ) {
1516
+        $post = get_post( $post_id );
1517
+
1518
+        if ( $post && 'attachment' === $post->post_type ) {
1519
+            $attachments = array( $post->ID => $post );
1520
+        } else {
1521
+            $attachments = get_children(
1522
+                array(
1523
+                    'post_parent' => $post_id,
1524
+                    'post_type'   => 'attachment',
1525
+                    'orderby'     => 'menu_order ASC, ID',
1526
+                    'order'       => 'DESC',
1527
+                )
1528
+            );
1529
+        }
1530
+    } else {
1531
+        if ( is_array( $GLOBALS['wp_the_query']->posts ) ) {
1532
+            foreach ( $GLOBALS['wp_the_query']->posts as $attachment ) {
1533
+                $attachments[ $attachment->ID ] = $attachment;
1534
+            }
1535
+        }
1536
+    }
1537
+
1538
+    $output = '';
1539
+    foreach ( (array) $attachments as $id => $attachment ) {
1540
+        if ( 'trash' === $attachment->post_status ) {
1541
+            continue;
1542
+        }
1543
+
1544
+        $item = get_media_item( $id, array( 'errors' => isset( $errors[ $id ] ) ? $errors[ $id ] : null ) );
1545
+
1546
+        if ( $item ) {
1547
+            $output .= "\n<div id='media-item-$id' class='media-item child-of-$attachment->post_parent preloaded'><div class='progress hidden'><div class='bar'></div></div><div id='media-upload-error-$id' class='hidden'></div><div class='filename hidden'></div>$item\n</div>";
1548
+        }
1549
+    }
1550
+
1551
+    return $output;
1552 1552
 }
1553 1553
 
1554 1554
 /**
@@ -1562,289 +1562,289 @@  discard block
 block discarded – undo
1562 1562
  * @param string|array $args          Optional. Override defaults.
1563 1563
  * @return string HTML form for attachment.
1564 1564
  */
1565
-function get_media_item( $attachment_id, $args = null ) {
1566
-	global $redir_tab;
1567
-
1568
-	$thumb_url     = false;
1569
-	$attachment_id = (int) $attachment_id;
1570
-
1571
-	if ( $attachment_id ) {
1572
-		$thumb_url = wp_get_attachment_image_src( $attachment_id, 'thumbnail', true );
1573
-
1574
-		if ( $thumb_url ) {
1575
-			$thumb_url = $thumb_url[0];
1576
-		}
1577
-	}
1578
-
1579
-	$post            = get_post( $attachment_id );
1580
-	$current_post_id = ! empty( $_GET['post_id'] ) ? (int) $_GET['post_id'] : 0;
1581
-
1582
-	$default_args = array(
1583
-		'errors'     => null,
1584
-		'send'       => $current_post_id ? post_type_supports( get_post_type( $current_post_id ), 'editor' ) : true,
1585
-		'delete'     => true,
1586
-		'toggle'     => true,
1587
-		'show_title' => true,
1588
-	);
1589
-
1590
-	$parsed_args = wp_parse_args( $args, $default_args );
1591
-
1592
-	/**
1593
-	 * Filters the arguments used to retrieve an image for the edit image form.
1594
-	 *
1595
-	 * @since 3.1.0
1596
-	 *
1597
-	 * @see get_media_item
1598
-	 *
1599
-	 * @param array $parsed_args An array of arguments.
1600
-	 */
1601
-	$parsed_args = apply_filters( 'get_media_item_args', $parsed_args );
1602
-
1603
-	$toggle_on  = __( 'Show' );
1604
-	$toggle_off = __( 'Hide' );
1605
-
1606
-	$file     = get_attached_file( $post->ID );
1607
-	$filename = esc_html( wp_basename( $file ) );
1608
-	$title    = esc_attr( $post->post_title );
1609
-
1610
-	$post_mime_types = get_post_mime_types();
1611
-	$keys            = array_keys( wp_match_mime_types( array_keys( $post_mime_types ), $post->post_mime_type ) );
1612
-	$type            = reset( $keys );
1613
-	$type_html       = "<input type='hidden' id='type-of-$attachment_id' value='" . esc_attr( $type ) . "' />";
1614
-
1615
-	$form_fields = get_attachment_fields_to_edit( $post, $parsed_args['errors'] );
1616
-
1617
-	if ( $parsed_args['toggle'] ) {
1618
-		$class        = empty( $parsed_args['errors'] ) ? 'startclosed' : 'startopen';
1619
-		$toggle_links = "
1620
-		<a class='toggle describe-toggle-on' href='#'>$toggle_on</a>
1621
-		<a class='toggle describe-toggle-off' href='#'>$toggle_off</a>";
1622
-	} else {
1623
-		$class        = '';
1624
-		$toggle_links = '';
1625
-	}
1626
-
1627
-	$display_title = ( ! empty( $title ) ) ? $title : $filename; // $title shouldn't ever be empty, but just in case.
1628
-	$display_title = $parsed_args['show_title'] ? "<div class='filename new'><span class='title'>" . wp_html_excerpt( $display_title, 60, '&hellip;' ) . '</span></div>' : '';
1629
-
1630
-	$gallery = ( ( isset( $_REQUEST['tab'] ) && 'gallery' === $_REQUEST['tab'] ) || ( isset( $redir_tab ) && 'gallery' === $redir_tab ) );
1631
-	$order   = '';
1632
-
1633
-	foreach ( $form_fields as $key => $val ) {
1634
-		if ( 'menu_order' === $key ) {
1635
-			if ( $gallery ) {
1636
-				$order = "<div class='menu_order'> <input class='menu_order_input' type='text' id='attachments[$attachment_id][menu_order]' name='attachments[$attachment_id][menu_order]' value='" . esc_attr( $val['value'] ) . "' /></div>";
1637
-			} else {
1638
-				$order = "<input type='hidden' name='attachments[$attachment_id][menu_order]' value='" . esc_attr( $val['value'] ) . "' />";
1639
-			}
1640
-
1641
-			unset( $form_fields['menu_order'] );
1642
-			break;
1643
-		}
1644
-	}
1645
-
1646
-	$media_dims = '';
1647
-	$meta       = wp_get_attachment_metadata( $post->ID );
1648
-
1649
-	if ( isset( $meta['width'], $meta['height'] ) ) {
1650
-		$media_dims .= "<span id='media-dims-$post->ID'>{$meta['width']}&nbsp;&times;&nbsp;{$meta['height']}</span> ";
1651
-	}
1652
-
1653
-	/**
1654
-	 * Filters the media metadata.
1655
-	 *
1656
-	 * @since 2.5.0
1657
-	 *
1658
-	 * @param string  $media_dims The HTML markup containing the media dimensions.
1659
-	 * @param WP_Post $post       The WP_Post attachment object.
1660
-	 */
1661
-	$media_dims = apply_filters( 'media_meta', $media_dims, $post );
1662
-
1663
-	$image_edit_button = '';
1664
-
1665
-	if ( wp_attachment_is_image( $post->ID ) && wp_image_editor_supports( array( 'mime_type' => $post->post_mime_type ) ) ) {
1666
-		$nonce             = wp_create_nonce( "image_editor-$post->ID" );
1667
-		$image_edit_button = "<input type='button' id='imgedit-open-btn-$post->ID' onclick='imageEdit.open( $post->ID, \"$nonce\" )' class='button' value='" . esc_attr__( 'Edit Image' ) . "' /> <span class='spinner'></span>";
1668
-	}
1669
-
1670
-	$attachment_url = get_permalink( $attachment_id );
1671
-
1672
-	$item = "
1673
-		$type_html
1674
-		$toggle_links
1675
-		$order
1676
-		$display_title
1677
-		<table class='slidetoggle describe $class'>
1678
-			<thead class='media-item-info' id='media-head-$post->ID'>
1679
-			<tr>
1680
-			<td class='A1B1' id='thumbnail-head-$post->ID'>
1681
-			<p><a href='$attachment_url' target='_blank'><img class='thumbnail' src='$thumb_url' alt='' /></a></p>
1682
-			<p>$image_edit_button</p>
1683
-			</td>
1684
-			<td>
1685
-			<p><strong>" . __( 'File name:' ) . "</strong> $filename</p>
1686
-			<p><strong>" . __( 'File type:' ) . "</strong> $post->post_mime_type</p>
1687
-			<p><strong>" . __( 'Upload date:' ) . '</strong> ' . mysql2date( __( 'F j, Y' ), $post->post_date ) . '</p>';
1688
-
1689
-	if ( ! empty( $media_dims ) ) {
1690
-		$item .= '<p><strong>' . __( 'Dimensions:' ) . "</strong> $media_dims</p>\n";
1691
-	}
1692
-
1693
-	$item .= "</td></tr>\n";
1694
-
1695
-	$item .= "
1696
-		</thead>
1697
-		<tbody>
1698
-		<tr><td colspan='2' class='imgedit-response' id='imgedit-response-$post->ID'></td></tr>\n
1699
-		<tr><td style='display:none' colspan='2' class='image-editor' id='image-editor-$post->ID'></td></tr>\n
1700
-		<tr><td colspan='2'><p class='media-types media-types-required-info'>" .
1701
-			/* translators: %s: Asterisk symbol (*). */
1702
-			sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
1703
-		"</p></td></tr>\n";
1704
-
1705
-	$defaults = array(
1706
-		'input'      => 'text',
1707
-		'required'   => false,
1708
-		'value'      => '',
1709
-		'extra_rows' => array(),
1710
-	);
1711
-
1712
-	if ( $parsed_args['send'] ) {
1713
-		$parsed_args['send'] = get_submit_button( __( 'Insert into Post' ), '', "send[$attachment_id]", false );
1714
-	}
1715
-
1716
-	$delete = empty( $parsed_args['delete'] ) ? '' : $parsed_args['delete'];
1717
-	if ( $delete && current_user_can( 'delete_post', $attachment_id ) ) {
1718
-		if ( ! EMPTY_TRASH_DAYS ) {
1719
-			$delete = "<a href='" . wp_nonce_url( "post.php?action=delete&amp;post=$attachment_id", 'delete-post_' . $attachment_id ) . "' id='del[$attachment_id]' class='delete-permanently'>" . __( 'Delete Permanently' ) . '</a>';
1720
-		} elseif ( ! MEDIA_TRASH ) {
1721
-			$delete = "<a href='#' class='del-link' onclick=\"document.getElementById('del_attachment_$attachment_id').style.display='block';return false;\">" . __( 'Delete' ) . "</a>
1722
-				<div id='del_attachment_$attachment_id' class='del-attachment' style='display:none;'>" .
1723
-				/* translators: %s: File name. */
1724
-				'<p>' . sprintf( __( 'You are about to delete %s.' ), '<strong>' . $filename . '</strong>' ) . "</p>
1725
-				<a href='" . wp_nonce_url( "post.php?action=delete&amp;post=$attachment_id", 'delete-post_' . $attachment_id ) . "' id='del[$attachment_id]' class='button'>" . __( 'Continue' ) . "</a>
1726
-				<a href='#' class='button' onclick=\"this.parentNode.style.display='none';return false;\">" . __( 'Cancel' ) . '</a>
1727
-				</div>';
1728
-		} else {
1729
-			$delete = "<a href='" . wp_nonce_url( "post.php?action=trash&amp;post=$attachment_id", 'trash-post_' . $attachment_id ) . "' id='del[$attachment_id]' class='delete'>" . __( 'Move to Trash' ) . "</a>
1730
-			<a href='" . wp_nonce_url( "post.php?action=untrash&amp;post=$attachment_id", 'untrash-post_' . $attachment_id ) . "' id='undo[$attachment_id]' class='undo hidden'>" . __( 'Undo' ) . '</a>';
1731
-		}
1732
-	} else {
1733
-		$delete = '';
1734
-	}
1735
-
1736
-	$thumbnail       = '';
1737
-	$calling_post_id = 0;
1738
-
1739
-	if ( isset( $_GET['post_id'] ) ) {
1740
-		$calling_post_id = absint( $_GET['post_id'] );
1741
-	} elseif ( isset( $_POST ) && count( $_POST ) ) {// Like for async-upload where $_GET['post_id'] isn't set.
1742
-		$calling_post_id = $post->post_parent;
1743
-	}
1744
-
1745
-	if ( 'image' === $type && $calling_post_id
1746
-		&& current_theme_supports( 'post-thumbnails', get_post_type( $calling_post_id ) )
1747
-		&& post_type_supports( get_post_type( $calling_post_id ), 'thumbnail' )
1748
-		&& get_post_thumbnail_id( $calling_post_id ) != $attachment_id
1749
-	) {
1750
-
1751
-		$calling_post             = get_post( $calling_post_id );
1752
-		$calling_post_type_object = get_post_type_object( $calling_post->post_type );
1753
-
1754
-		$ajax_nonce = wp_create_nonce( "set_post_thumbnail-$calling_post_id" );
1755
-		$thumbnail  = "<a class='wp-post-thumbnail' id='wp-post-thumbnail-" . $attachment_id . "' href='#' onclick='WPSetAsThumbnail(\"$attachment_id\", \"$ajax_nonce\");return false;'>" . esc_html( $calling_post_type_object->labels->use_featured_image ) . '</a>';
1756
-	}
1757
-
1758
-	if ( ( $parsed_args['send'] || $thumbnail || $delete ) && ! isset( $form_fields['buttons'] ) ) {
1759
-		$form_fields['buttons'] = array( 'tr' => "\t\t<tr class='submit'><td></td><td class='savesend'>" . $parsed_args['send'] . " $thumbnail $delete</td></tr>\n" );
1760
-	}
1761
-
1762
-	$hidden_fields = array();
1763
-
1764
-	foreach ( $form_fields as $id => $field ) {
1765
-		if ( '_' === $id[0] ) {
1766
-			continue;
1767
-		}
1768
-
1769
-		if ( ! empty( $field['tr'] ) ) {
1770
-			$item .= $field['tr'];
1771
-			continue;
1772
-		}
1773
-
1774
-		$field = array_merge( $defaults, $field );
1775
-		$name  = "attachments[$attachment_id][$id]";
1776
-
1777
-		if ( 'hidden' === $field['input'] ) {
1778
-			$hidden_fields[ $name ] = $field['value'];
1779
-			continue;
1780
-		}
1781
-
1782
-		$required      = $field['required'] ? '<span class="required">*</span>' : '';
1783
-		$required_attr = $field['required'] ? ' required' : '';
1784
-		$class         = $id;
1785
-		$class        .= $field['required'] ? ' form-required' : '';
1786
-
1787
-		$item .= "\t\t<tr class='$class'>\n\t\t\t<th scope='row' class='label'><label for='$name'><span class='alignleft'>{$field['label']}{$required}</span><br class='clear' /></label></th>\n\t\t\t<td class='field'>";
1788
-
1789
-		if ( ! empty( $field[ $field['input'] ] ) ) {
1790
-			$item .= $field[ $field['input'] ];
1791
-		} elseif ( 'textarea' === $field['input'] ) {
1792
-			if ( 'post_content' === $id && user_can_richedit() ) {
1793
-				// Sanitize_post() skips the post_content when user_can_richedit.
1794
-				$field['value'] = htmlspecialchars( $field['value'], ENT_QUOTES );
1795
-			}
1796
-			// Post_excerpt is already escaped by sanitize_post() in get_attachment_fields_to_edit().
1797
-			$item .= "<textarea id='$name' name='$name'{$required_attr}>" . $field['value'] . '</textarea>';
1798
-		} else {
1799
-			$item .= "<input type='text' class='text' id='$name' name='$name' value='" . esc_attr( $field['value'] ) . "'{$required_attr} />";
1800
-		}
1801
-
1802
-		if ( ! empty( $field['helps'] ) ) {
1803
-			$item .= "<p class='help'>" . implode( "</p>\n<p class='help'>", array_unique( (array) $field['helps'] ) ) . '</p>';
1804
-		}
1805
-		$item .= "</td>\n\t\t</tr>\n";
1806
-
1807
-		$extra_rows = array();
1808
-
1809
-		if ( ! empty( $field['errors'] ) ) {
1810
-			foreach ( array_unique( (array) $field['errors'] ) as $error ) {
1811
-				$extra_rows['error'][] = $error;
1812
-			}
1813
-		}
1814
-
1815
-		if ( ! empty( $field['extra_rows'] ) ) {
1816
-			foreach ( $field['extra_rows'] as $class => $rows ) {
1817
-				foreach ( (array) $rows as $html ) {
1818
-					$extra_rows[ $class ][] = $html;
1819
-				}
1820
-			}
1821
-		}
1822
-
1823
-		foreach ( $extra_rows as $class => $rows ) {
1824
-			foreach ( $rows as $html ) {
1825
-				$item .= "\t\t<tr><td></td><td class='$class'>$html</td></tr>\n";
1826
-			}
1827
-		}
1828
-	}
1829
-
1830
-	if ( ! empty( $form_fields['_final'] ) ) {
1831
-		$item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
1832
-	}
1833
-
1834
-	$item .= "\t</tbody>\n";
1835
-	$item .= "\t</table>\n";
1565
+function get_media_item( $attachment_id, $args = null ) {
1566
+    global $redir_tab;
1567
+
1568
+    $thumb_url     = false;
1569
+    $attachment_id = (int) $attachment_id;
1570
+
1571
+    if ( $attachment_id ) {
1572
+        $thumb_url = wp_get_attachment_image_src( $attachment_id, 'thumbnail', true );
1573
+
1574
+        if ( $thumb_url ) {
1575
+            $thumb_url = $thumb_url[0];
1576
+        }
1577
+    }
1578
+
1579
+    $post            = get_post( $attachment_id );
1580
+    $current_post_id = ! empty( $_GET['post_id'] ) ? (int) $_GET['post_id'] : 0;
1581
+
1582
+    $default_args = array(
1583
+        'errors'     => null,
1584
+        'send'       => $current_post_id ? post_type_supports( get_post_type( $current_post_id ), 'editor' ) : true,
1585
+        'delete'     => true,
1586
+        'toggle'     => true,
1587
+        'show_title' => true,
1588
+    );
1589
+
1590
+    $parsed_args = wp_parse_args( $args, $default_args );
1591
+
1592
+    /**
1593
+     * Filters the arguments used to retrieve an image for the edit image form.
1594
+     *
1595
+     * @since 3.1.0
1596
+     *
1597
+     * @see get_media_item
1598
+     *
1599
+     * @param array $parsed_args An array of arguments.
1600
+     */
1601
+    $parsed_args = apply_filters( 'get_media_item_args', $parsed_args );
1602
+
1603
+    $toggle_on  = __( 'Show' );
1604
+    $toggle_off = __( 'Hide' );
1605
+
1606
+    $file     = get_attached_file( $post->ID );
1607
+    $filename = esc_html( wp_basename( $file ) );
1608
+    $title    = esc_attr( $post->post_title );
1609
+
1610
+    $post_mime_types = get_post_mime_types();
1611
+    $keys            = array_keys( wp_match_mime_types( array_keys( $post_mime_types ), $post->post_mime_type ) );
1612
+    $type            = reset( $keys );
1613
+    $type_html       = "<input type='hidden' id='type-of-$attachment_id' value='" . esc_attr( $type ) . "' />";
1614
+
1615
+    $form_fields = get_attachment_fields_to_edit( $post, $parsed_args['errors'] );
1616
+
1617
+    if ( $parsed_args['toggle'] ) {
1618
+        $class        = empty( $parsed_args['errors'] ) ? 'startclosed' : 'startopen';
1619
+        $toggle_links = "
1620
+		<a class='toggle describe-toggle-on' href='#'>$toggle_on</a>
1621
+		<a class='toggle describe-toggle-off' href='#'>$toggle_off</a>";
1622
+    } else {
1623
+        $class        = '';
1624
+        $toggle_links = '';
1625
+    }
1626
+
1627
+    $display_title = ( ! empty( $title ) ) ? $title : $filename; // $title shouldn't ever be empty, but just in case.
1628
+    $display_title = $parsed_args['show_title'] ? "<div class='filename new'><span class='title'>" . wp_html_excerpt( $display_title, 60, '&hellip;' ) . '</span></div>' : '';
1629
+
1630
+    $gallery = ( ( isset( $_REQUEST['tab'] ) && 'gallery' === $_REQUEST['tab'] ) || ( isset( $redir_tab ) && 'gallery' === $redir_tab ) );
1631
+    $order   = '';
1632
+
1633
+    foreach ( $form_fields as $key => $val ) {
1634
+        if ( 'menu_order' === $key ) {
1635
+            if ( $gallery ) {
1636
+                $order = "<div class='menu_order'> <input class='menu_order_input' type='text' id='attachments[$attachment_id][menu_order]' name='attachments[$attachment_id][menu_order]' value='" . esc_attr( $val['value'] ) . "' /></div>";
1637
+            } else {
1638
+                $order = "<input type='hidden' name='attachments[$attachment_id][menu_order]' value='" . esc_attr( $val['value'] ) . "' />";
1639
+            }
1640
+
1641
+            unset( $form_fields['menu_order'] );
1642
+            break;
1643
+        }
1644
+    }
1645
+
1646
+    $media_dims = '';
1647
+    $meta       = wp_get_attachment_metadata( $post->ID );
1648
+
1649
+    if ( isset( $meta['width'], $meta['height'] ) ) {
1650
+        $media_dims .= "<span id='media-dims-$post->ID'>{$meta['width']}&nbsp;&times;&nbsp;{$meta['height']}</span> ";
1651
+    }
1652
+
1653
+    /**
1654
+     * Filters the media metadata.
1655
+     *
1656
+     * @since 2.5.0
1657
+     *
1658
+     * @param string  $media_dims The HTML markup containing the media dimensions.
1659
+     * @param WP_Post $post       The WP_Post attachment object.
1660
+     */
1661
+    $media_dims = apply_filters( 'media_meta', $media_dims, $post );
1662
+
1663
+    $image_edit_button = '';
1664
+
1665
+    if ( wp_attachment_is_image( $post->ID ) && wp_image_editor_supports( array( 'mime_type' => $post->post_mime_type ) ) ) {
1666
+        $nonce             = wp_create_nonce( "image_editor-$post->ID" );
1667
+        $image_edit_button = "<input type='button' id='imgedit-open-btn-$post->ID' onclick='imageEdit.open( $post->ID, \"$nonce\" )' class='button' value='" . esc_attr__( 'Edit Image' ) . "' /> <span class='spinner'></span>";
1668
+    }
1669
+
1670
+    $attachment_url = get_permalink( $attachment_id );
1671
+
1672
+    $item = "
1673
+		$type_html
1674
+		$toggle_links
1675
+		$order
1676
+		$display_title
1677
+		<table class='slidetoggle describe $class'>
1678
+			<thead class='media-item-info' id='media-head-$post->ID'>
1679
+			<tr>
1680
+			<td class='A1B1' id='thumbnail-head-$post->ID'>
1681
+			<p><a href='$attachment_url' target='_blank'><img class='thumbnail' src='$thumb_url' alt='' /></a></p>
1682
+			<p>$image_edit_button</p>
1683
+			</td>
1684
+			<td>
1685
+			<p><strong>" . __( 'File name:' ) . "</strong> $filename</p>
1686
+			<p><strong>" . __( 'File type:' ) . "</strong> $post->post_mime_type</p>
1687
+			<p><strong>" . __( 'Upload date:' ) . '</strong> ' . mysql2date( __( 'F j, Y' ), $post->post_date ) . '</p>';
1836 1688
 
1837
-	foreach ( $hidden_fields as $name => $value ) {
1838
-		$item .= "\t<input type='hidden' name='$name' id='$name' value='" . esc_attr( $value ) . "' />\n";
1839
-	}
1689
+    if ( ! empty( $media_dims ) ) {
1690
+        $item .= '<p><strong>' . __( 'Dimensions:' ) . "</strong> $media_dims</p>\n";
1691
+    }
1840 1692
 
1841
-	if ( $post->post_parent < 1 && isset( $_REQUEST['post_id'] ) ) {
1842
-		$parent      = (int) $_REQUEST['post_id'];
1843
-		$parent_name = "attachments[$attachment_id][post_parent]";
1844
-		$item       .= "\t<input type='hidden' name='$parent_name' id='$parent_name' value='$parent' />\n";
1845
-	}
1693
+    $item .= "</td></tr>\n";
1846 1694
 
1847
-	return $item;
1695
+    $item .= "
1696
+		</thead>
1697
+		<tbody>
1698
+		<tr><td colspan='2' class='imgedit-response' id='imgedit-response-$post->ID'></td></tr>\n
1699
+		<tr><td style='display:none' colspan='2' class='image-editor' id='image-editor-$post->ID'></td></tr>\n
1700
+		<tr><td colspan='2'><p class='media-types media-types-required-info'>" .
1701
+            /* translators: %s: Asterisk symbol (*). */
1702
+            sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
1703
+        "</p></td></tr>\n";
1704
+
1705
+    $defaults = array(
1706
+        'input'      => 'text',
1707
+        'required'   => false,
1708
+        'value'      => '',
1709
+        'extra_rows' => array(),
1710
+    );
1711
+
1712
+    if ( $parsed_args['send'] ) {
1713
+        $parsed_args['send'] = get_submit_button( __( 'Insert into Post' ), '', "send[$attachment_id]", false );
1714
+    }
1715
+
1716
+    $delete = empty( $parsed_args['delete'] ) ? '' : $parsed_args['delete'];
1717
+    if ( $delete && current_user_can( 'delete_post', $attachment_id ) ) {
1718
+        if ( ! EMPTY_TRASH_DAYS ) {
1719
+            $delete = "<a href='" . wp_nonce_url( "post.php?action=delete&amp;post=$attachment_id", 'delete-post_' . $attachment_id ) . "' id='del[$attachment_id]' class='delete-permanently'>" . __( 'Delete Permanently' ) . '</a>';
1720
+        } elseif ( ! MEDIA_TRASH ) {
1721
+            $delete = "<a href='#' class='del-link' onclick=\"document.getElementById('del_attachment_$attachment_id').style.display='block';return false;\">" . __( 'Delete' ) . "</a>
1722
+				<div id='del_attachment_$attachment_id' class='del-attachment' style='display:none;'>" .
1723
+                /* translators: %s: File name. */
1724
+                '<p>' . sprintf( __( 'You are about to delete %s.' ), '<strong>' . $filename . '</strong>' ) . "</p>
1725
+				<a href='" . wp_nonce_url( "post.php?action=delete&amp;post=$attachment_id", 'delete-post_' . $attachment_id ) . "' id='del[$attachment_id]' class='button'>" . __( 'Continue' ) . "</a>
1726
+				<a href='#' class='button' onclick=\"this.parentNode.style.display='none';return false;\">" . __( 'Cancel' ) . '</a>
1727
+				</div>';
1728
+        } else {
1729
+            $delete = "<a href='" . wp_nonce_url( "post.php?action=trash&amp;post=$attachment_id", 'trash-post_' . $attachment_id ) . "' id='del[$attachment_id]' class='delete'>" . __( 'Move to Trash' ) . "</a>
1730
+			<a href='" . wp_nonce_url( "post.php?action=untrash&amp;post=$attachment_id", 'untrash-post_' . $attachment_id ) . "' id='undo[$attachment_id]' class='undo hidden'>" . __( 'Undo' ) . '</a>';
1731
+        }
1732
+    } else {
1733
+        $delete = '';
1734
+    }
1735
+
1736
+    $thumbnail       = '';
1737
+    $calling_post_id = 0;
1738
+
1739
+    if ( isset( $_GET['post_id'] ) ) {
1740
+        $calling_post_id = absint( $_GET['post_id'] );
1741
+    } elseif ( isset( $_POST ) && count( $_POST ) ) {// Like for async-upload where $_GET['post_id'] isn't set.
1742
+        $calling_post_id = $post->post_parent;
1743
+    }
1744
+
1745
+    if ( 'image' === $type && $calling_post_id
1746
+        && current_theme_supports( 'post-thumbnails', get_post_type( $calling_post_id ) )
1747
+        && post_type_supports( get_post_type( $calling_post_id ), 'thumbnail' )
1748
+        && get_post_thumbnail_id( $calling_post_id ) != $attachment_id
1749
+    ) {
1750
+
1751
+        $calling_post             = get_post( $calling_post_id );
1752
+        $calling_post_type_object = get_post_type_object( $calling_post->post_type );
1753
+
1754
+        $ajax_nonce = wp_create_nonce( "set_post_thumbnail-$calling_post_id" );
1755
+        $thumbnail  = "<a class='wp-post-thumbnail' id='wp-post-thumbnail-" . $attachment_id . "' href='#' onclick='WPSetAsThumbnail(\"$attachment_id\", \"$ajax_nonce\");return false;'>" . esc_html( $calling_post_type_object->labels->use_featured_image ) . '</a>';
1756
+    }
1757
+
1758
+    if ( ( $parsed_args['send'] || $thumbnail || $delete ) && ! isset( $form_fields['buttons'] ) ) {
1759
+        $form_fields['buttons'] = array( 'tr' => "\t\t<tr class='submit'><td></td><td class='savesend'>" . $parsed_args['send'] . " $thumbnail $delete</td></tr>\n" );
1760
+    }
1761
+
1762
+    $hidden_fields = array();
1763
+
1764
+    foreach ( $form_fields as $id => $field ) {
1765
+        if ( '_' === $id[0] ) {
1766
+            continue;
1767
+        }
1768
+
1769
+        if ( ! empty( $field['tr'] ) ) {
1770
+            $item .= $field['tr'];
1771
+            continue;
1772
+        }
1773
+
1774
+        $field = array_merge( $defaults, $field );
1775
+        $name  = "attachments[$attachment_id][$id]";
1776
+
1777
+        if ( 'hidden' === $field['input'] ) {
1778
+            $hidden_fields[ $name ] = $field['value'];
1779
+            continue;
1780
+        }
1781
+
1782
+        $required      = $field['required'] ? '<span class="required">*</span>' : '';
1783
+        $required_attr = $field['required'] ? ' required' : '';
1784
+        $class         = $id;
1785
+        $class        .= $field['required'] ? ' form-required' : '';
1786
+
1787
+        $item .= "\t\t<tr class='$class'>\n\t\t\t<th scope='row' class='label'><label for='$name'><span class='alignleft'>{$field['label']}{$required}</span><br class='clear' /></label></th>\n\t\t\t<td class='field'>";
1788
+
1789
+        if ( ! empty( $field[ $field['input'] ] ) ) {
1790
+            $item .= $field[ $field['input'] ];
1791
+        } elseif ( 'textarea' === $field['input'] ) {
1792
+            if ( 'post_content' === $id && user_can_richedit() ) {
1793
+                // Sanitize_post() skips the post_content when user_can_richedit.
1794
+                $field['value'] = htmlspecialchars( $field['value'], ENT_QUOTES );
1795
+            }
1796
+            // Post_excerpt is already escaped by sanitize_post() in get_attachment_fields_to_edit().
1797
+            $item .= "<textarea id='$name' name='$name'{$required_attr}>" . $field['value'] . '</textarea>';
1798
+        } else {
1799
+            $item .= "<input type='text' class='text' id='$name' name='$name' value='" . esc_attr( $field['value'] ) . "'{$required_attr} />";
1800
+        }
1801
+
1802
+        if ( ! empty( $field['helps'] ) ) {
1803
+            $item .= "<p class='help'>" . implode( "</p>\n<p class='help'>", array_unique( (array) $field['helps'] ) ) . '</p>';
1804
+        }
1805
+        $item .= "</td>\n\t\t</tr>\n";
1806
+
1807
+        $extra_rows = array();
1808
+
1809
+        if ( ! empty( $field['errors'] ) ) {
1810
+            foreach ( array_unique( (array) $field['errors'] ) as $error ) {
1811
+                $extra_rows['error'][] = $error;
1812
+            }
1813
+        }
1814
+
1815
+        if ( ! empty( $field['extra_rows'] ) ) {
1816
+            foreach ( $field['extra_rows'] as $class => $rows ) {
1817
+                foreach ( (array) $rows as $html ) {
1818
+                    $extra_rows[ $class ][] = $html;
1819
+                }
1820
+            }
1821
+        }
1822
+
1823
+        foreach ( $extra_rows as $class => $rows ) {
1824
+            foreach ( $rows as $html ) {
1825
+                $item .= "\t\t<tr><td></td><td class='$class'>$html</td></tr>\n";
1826
+            }
1827
+        }
1828
+    }
1829
+
1830
+    if ( ! empty( $form_fields['_final'] ) ) {
1831
+        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
1832
+    }
1833
+
1834
+    $item .= "\t</tbody>\n";
1835
+    $item .= "\t</table>\n";
1836
+
1837
+    foreach ( $hidden_fields as $name => $value ) {
1838
+        $item .= "\t<input type='hidden' name='$name' id='$name' value='" . esc_attr( $value ) . "' />\n";
1839
+    }
1840
+
1841
+    if ( $post->post_parent < 1 && isset( $_REQUEST['post_id'] ) ) {
1842
+        $parent      = (int) $_REQUEST['post_id'];
1843
+        $parent_name = "attachments[$attachment_id][post_parent]";
1844
+        $item       .= "\t<input type='hidden' name='$parent_name' id='$parent_name' value='$parent' />\n";
1845
+    }
1846
+
1847
+    return $item;
1848 1848
 }
1849 1849
 
1850 1850
 /**
@@ -1855,195 +1855,195 @@  discard block
 block discarded – undo
1855 1855
  * @return array
1856 1856
  */
1857 1857
 function get_compat_media_markup( $attachment_id, $args = null ) {
1858
-	$post = get_post( $attachment_id );
1858
+    $post = get_post( $attachment_id );
1859 1859
 
1860
-	$default_args = array(
1861
-		'errors'   => null,
1862
-		'in_modal' => false,
1863
-	);
1860
+    $default_args = array(
1861
+        'errors'   => null,
1862
+        'in_modal' => false,
1863
+    );
1864 1864
 
1865
-	$user_can_edit = current_user_can( 'edit_post', $attachment_id );
1865
+    $user_can_edit = current_user_can( 'edit_post', $attachment_id );
1866 1866
 
1867
-	$args = wp_parse_args( $args, $default_args );
1867
+    $args = wp_parse_args( $args, $default_args );
1868 1868
 
1869
-	/** This filter is documented in wp-admin/includes/media.php */
1870
-	$args = apply_filters( 'get_media_item_args', $args );
1869
+    /** This filter is documented in wp-admin/includes/media.php */
1870
+    $args = apply_filters( 'get_media_item_args', $args );
1871 1871
 
1872
-	$form_fields = array();
1872
+    $form_fields = array();
1873 1873
 
1874
-	if ( $args['in_modal'] ) {
1875
-		foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
1876
-			$t = (array) get_taxonomy( $taxonomy );
1874
+    if ( $args['in_modal'] ) {
1875
+        foreach ( get_attachment_taxonomies( $post ) as $taxonomy ) {
1876
+            $t = (array) get_taxonomy( $taxonomy );
1877 1877
 
1878
-			if ( ! $t['public'] || ! $t['show_ui'] ) {
1879
-				continue;
1880
-			}
1878
+            if ( ! $t['public'] || ! $t['show_ui'] ) {
1879
+                continue;
1880
+            }
1881 1881
 
1882
-			if ( empty( $t['label'] ) ) {
1883
-				$t['label'] = $taxonomy;
1884
-			}
1882
+            if ( empty( $t['label'] ) ) {
1883
+                $t['label'] = $taxonomy;
1884
+            }
1885 1885
 
1886
-			if ( empty( $t['args'] ) ) {
1887
-				$t['args'] = array();
1888
-			}
1886
+            if ( empty( $t['args'] ) ) {
1887
+                $t['args'] = array();
1888
+            }
1889 1889
 
1890
-			$terms = get_object_term_cache( $post->ID, $taxonomy );
1890
+            $terms = get_object_term_cache( $post->ID, $taxonomy );
1891 1891
 
1892
-			if ( false === $terms ) {
1893
-				$terms = wp_get_object_terms( $post->ID, $taxonomy, $t['args'] );
1894
-			}
1892
+            if ( false === $terms ) {
1893
+                $terms = wp_get_object_terms( $post->ID, $taxonomy, $t['args'] );
1894
+            }
1895 1895
 
1896
-			$values = array();
1896
+            $values = array();
1897 1897
 
1898
-			foreach ( $terms as $term ) {
1899
-				$values[] = $term->slug;
1900
-			}
1898
+            foreach ( $terms as $term ) {
1899
+                $values[] = $term->slug;
1900
+            }
1901 1901
 
1902
-			$t['value']    = implode( ', ', $values );
1903
-			$t['taxonomy'] = true;
1902
+            $t['value']    = implode( ', ', $values );
1903
+            $t['taxonomy'] = true;
1904 1904
 
1905
-			$form_fields[ $taxonomy ] = $t;
1906
-		}
1907
-	}
1905
+            $form_fields[ $taxonomy ] = $t;
1906
+        }
1907
+    }
1908 1908
 
1909
-	/*
1909
+    /*
1910 1910
 	 * Merge default fields with their errors, so any key passed with the error
1911 1911
 	 * (e.g. 'error', 'helps', 'value') will replace the default.
1912 1912
 	 * The recursive merge is easily traversed with array casting:
1913 1913
 	 * foreach ( (array) $things as $thing )
1914 1914
 	 */
1915
-	$form_fields = array_merge_recursive( $form_fields, (array) $args['errors'] );
1916
-
1917
-	/** This filter is documented in wp-admin/includes/media.php */
1918
-	$form_fields = apply_filters( 'attachment_fields_to_edit', $form_fields, $post );
1919
-
1920
-	unset(
1921
-		$form_fields['image-size'],
1922
-		$form_fields['align'],
1923
-		$form_fields['image_alt'],
1924
-		$form_fields['post_title'],
1925
-		$form_fields['post_excerpt'],
1926
-		$form_fields['post_content'],
1927
-		$form_fields['url'],
1928
-		$form_fields['menu_order'],
1929
-		$form_fields['image_url']
1930
-	);
1931
-
1932
-	/** This filter is documented in wp-admin/includes/media.php */
1933
-	$media_meta = apply_filters( 'media_meta', '', $post );
1934
-
1935
-	$defaults = array(
1936
-		'input'         => 'text',
1937
-		'required'      => false,
1938
-		'value'         => '',
1939
-		'extra_rows'    => array(),
1940
-		'show_in_edit'  => true,
1941
-		'show_in_modal' => true,
1942
-	);
1943
-
1944
-	$hidden_fields = array();
1945
-
1946
-	$item = '';
1947
-
1948
-	foreach ( $form_fields as $id => $field ) {
1949
-		if ( '_' === $id[0] ) {
1950
-			continue;
1951
-		}
1952
-
1953
-		$name    = "attachments[$attachment_id][$id]";
1954
-		$id_attr = "attachments-$attachment_id-$id";
1955
-
1956
-		if ( ! empty( $field['tr'] ) ) {
1957
-			$item .= $field['tr'];
1958
-			continue;
1959
-		}
1960
-
1961
-		$field = array_merge( $defaults, $field );
1962
-
1963
-		if ( ( ! $field['show_in_edit'] && ! $args['in_modal'] ) || ( ! $field['show_in_modal'] && $args['in_modal'] ) ) {
1964
-			continue;
1965
-		}
1966
-
1967
-		if ( 'hidden' === $field['input'] ) {
1968
-			$hidden_fields[ $name ] = $field['value'];
1969
-			continue;
1970
-		}
1971
-
1972
-		$readonly      = ! $user_can_edit && ! empty( $field['taxonomy'] ) ? " readonly='readonly' " : '';
1973
-		$required      = $field['required'] ? '<span class="required">*</span>' : '';
1974
-		$required_attr = $field['required'] ? ' required' : '';
1975
-		$class         = 'compat-field-' . $id;
1976
-		$class        .= $field['required'] ? ' form-required' : '';
1977
-
1978
-		$item .= "\t\t<tr class='$class'>";
1979
-		$item .= "\t\t\t<th scope='row' class='label'><label for='$id_attr'><span class='alignleft'>{$field['label']}</span>$required<br class='clear' /></label>";
1980
-		$item .= "</th>\n\t\t\t<td class='field'>";
1981
-
1982
-		if ( ! empty( $field[ $field['input'] ] ) ) {
1983
-			$item .= $field[ $field['input'] ];
1984
-		} elseif ( 'textarea' === $field['input'] ) {
1985
-			if ( 'post_content' === $id && user_can_richedit() ) {
1986
-				// sanitize_post() skips the post_content when user_can_richedit.
1987
-				$field['value'] = htmlspecialchars( $field['value'], ENT_QUOTES );
1988
-			}
1989
-			$item .= "<textarea id='$id_attr' name='$name'{$required_attr}>" . $field['value'] . '</textarea>';
1990
-		} else {
1991
-			$item .= "<input type='text' class='text' id='$id_attr' name='$name' value='" . esc_attr( $field['value'] ) . "' $readonly{$required_attr} />";
1992
-		}
1993
-
1994
-		if ( ! empty( $field['helps'] ) ) {
1995
-			$item .= "<p class='help'>" . implode( "</p>\n<p class='help'>", array_unique( (array) $field['helps'] ) ) . '</p>';
1996
-		}
1997
-
1998
-		$item .= "</td>\n\t\t</tr>\n";
1999
-
2000
-		$extra_rows = array();
2001
-
2002
-		if ( ! empty( $field['errors'] ) ) {
2003
-			foreach ( array_unique( (array) $field['errors'] ) as $error ) {
2004
-				$extra_rows['error'][] = $error;
2005
-			}
2006
-		}
2007
-
2008
-		if ( ! empty( $field['extra_rows'] ) ) {
2009
-			foreach ( $field['extra_rows'] as $class => $rows ) {
2010
-				foreach ( (array) $rows as $html ) {
2011
-					$extra_rows[ $class ][] = $html;
2012
-				}
2013
-			}
2014
-		}
2015
-
2016
-		foreach ( $extra_rows as $class => $rows ) {
2017
-			foreach ( $rows as $html ) {
2018
-				$item .= "\t\t<tr><td></td><td class='$class'>$html</td></tr>\n";
2019
-			}
2020
-		}
2021
-	}
2022
-
2023
-	if ( ! empty( $form_fields['_final'] ) ) {
2024
-		$item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
2025
-	}
2026
-
2027
-	if ( $item ) {
2028
-		$item = '<p class="media-types media-types-required-info">' .
2029
-			/* translators: %s: Asterisk symbol (*). */
2030
-			sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
2031
-			'</p>' .
2032
-			'<table class="compat-attachment-fields">' . $item . '</table>';
2033
-	}
2034
-
2035
-	foreach ( $hidden_fields as $hidden_field => $value ) {
2036
-		$item .= '<input type="hidden" name="' . esc_attr( $hidden_field ) . '" value="' . esc_attr( $value ) . '" />' . "\n";
2037
-	}
2038
-
2039
-	if ( $item ) {
2040
-		$item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr( $post->menu_order ) . '" />' . $item;
2041
-	}
2042
-
2043
-	return array(
2044
-		'item' => $item,
2045
-		'meta' => $media_meta,
2046
-	);
1915
+    $form_fields = array_merge_recursive( $form_fields, (array) $args['errors'] );
1916
+
1917
+    /** This filter is documented in wp-admin/includes/media.php */
1918
+    $form_fields = apply_filters( 'attachment_fields_to_edit', $form_fields, $post );
1919
+
1920
+    unset(
1921
+        $form_fields['image-size'],
1922
+        $form_fields['align'],
1923
+        $form_fields['image_alt'],
1924
+        $form_fields['post_title'],
1925
+        $form_fields['post_excerpt'],
1926
+        $form_fields['post_content'],
1927
+        $form_fields['url'],
1928
+        $form_fields['menu_order'],
1929
+        $form_fields['image_url']
1930
+    );
1931
+
1932
+    /** This filter is documented in wp-admin/includes/media.php */
1933
+    $media_meta = apply_filters( 'media_meta', '', $post );
1934
+
1935
+    $defaults = array(
1936
+        'input'         => 'text',
1937
+        'required'      => false,
1938
+        'value'         => '',
1939
+        'extra_rows'    => array(),
1940
+        'show_in_edit'  => true,
1941
+        'show_in_modal' => true,
1942
+    );
1943
+
1944
+    $hidden_fields = array();
1945
+
1946
+    $item = '';
1947
+
1948
+    foreach ( $form_fields as $id => $field ) {
1949
+        if ( '_' === $id[0] ) {
1950
+            continue;
1951
+        }
1952
+
1953
+        $name    = "attachments[$attachment_id][$id]";
1954
+        $id_attr = "attachments-$attachment_id-$id";
1955
+
1956
+        if ( ! empty( $field['tr'] ) ) {
1957
+            $item .= $field['tr'];
1958
+            continue;
1959
+        }
1960
+
1961
+        $field = array_merge( $defaults, $field );
1962
+
1963
+        if ( ( ! $field['show_in_edit'] && ! $args['in_modal'] ) || ( ! $field['show_in_modal'] && $args['in_modal'] ) ) {
1964
+            continue;
1965
+        }
1966
+
1967
+        if ( 'hidden' === $field['input'] ) {
1968
+            $hidden_fields[ $name ] = $field['value'];
1969
+            continue;
1970
+        }
1971
+
1972
+        $readonly      = ! $user_can_edit && ! empty( $field['taxonomy'] ) ? " readonly='readonly' " : '';
1973
+        $required      = $field['required'] ? '<span class="required">*</span>' : '';
1974
+        $required_attr = $field['required'] ? ' required' : '';
1975
+        $class         = 'compat-field-' . $id;
1976
+        $class        .= $field['required'] ? ' form-required' : '';
1977
+
1978
+        $item .= "\t\t<tr class='$class'>";
1979
+        $item .= "\t\t\t<th scope='row' class='label'><label for='$id_attr'><span class='alignleft'>{$field['label']}</span>$required<br class='clear' /></label>";
1980
+        $item .= "</th>\n\t\t\t<td class='field'>";
1981
+
1982
+        if ( ! empty( $field[ $field['input'] ] ) ) {
1983
+            $item .= $field[ $field['input'] ];
1984
+        } elseif ( 'textarea' === $field['input'] ) {
1985
+            if ( 'post_content' === $id && user_can_richedit() ) {
1986
+                // sanitize_post() skips the post_content when user_can_richedit.
1987
+                $field['value'] = htmlspecialchars( $field['value'], ENT_QUOTES );
1988
+            }
1989
+            $item .= "<textarea id='$id_attr' name='$name'{$required_attr}>" . $field['value'] . '</textarea>';
1990
+        } else {
1991
+            $item .= "<input type='text' class='text' id='$id_attr' name='$name' value='" . esc_attr( $field['value'] ) . "' $readonly{$required_attr} />";
1992
+        }
1993
+
1994
+        if ( ! empty( $field['helps'] ) ) {
1995
+            $item .= "<p class='help'>" . implode( "</p>\n<p class='help'>", array_unique( (array) $field['helps'] ) ) . '</p>';
1996
+        }
1997
+
1998
+        $item .= "</td>\n\t\t</tr>\n";
1999
+
2000
+        $extra_rows = array();
2001
+
2002
+        if ( ! empty( $field['errors'] ) ) {
2003
+            foreach ( array_unique( (array) $field['errors'] ) as $error ) {
2004
+                $extra_rows['error'][] = $error;
2005
+            }
2006
+        }
2007
+
2008
+        if ( ! empty( $field['extra_rows'] ) ) {
2009
+            foreach ( $field['extra_rows'] as $class => $rows ) {
2010
+                foreach ( (array) $rows as $html ) {
2011
+                    $extra_rows[ $class ][] = $html;
2012
+                }
2013
+            }
2014
+        }
2015
+
2016
+        foreach ( $extra_rows as $class => $rows ) {
2017
+            foreach ( $rows as $html ) {
2018
+                $item .= "\t\t<tr><td></td><td class='$class'>$html</td></tr>\n";
2019
+            }
2020
+        }
2021
+    }
2022
+
2023
+    if ( ! empty( $form_fields['_final'] ) ) {
2024
+        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
2025
+    }
2026
+
2027
+    if ( $item ) {
2028
+        $item = '<p class="media-types media-types-required-info">' .
2029
+            /* translators: %s: Asterisk symbol (*). */
2030
+            sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
2031
+            '</p>' .
2032
+            '<table class="compat-attachment-fields">' . $item . '</table>';
2033
+    }
2034
+
2035
+    foreach ( $hidden_fields as $hidden_field => $value ) {
2036
+        $item .= '<input type="hidden" name="' . esc_attr( $hidden_field ) . '" value="' . esc_attr( $value ) . '" />' . "\n";
2037
+    }
2038
+
2039
+    if ( $item ) {
2040
+        $item = '<input type="hidden" name="attachments[' . $attachment_id . '][menu_order]" value="' . esc_attr( $post->menu_order ) . '" />' . $item;
2041
+    }
2042
+
2043
+    return array(
2044
+        'item' => $item,
2045
+        'meta' => $media_meta,
2046
+    );
2047 2047
 }
2048 2048
 
2049 2049
 /**
@@ -2052,15 +2052,15 @@  discard block
 block discarded – undo
2052 2052
  * @since 2.5.0
2053 2053
  */
2054 2054
 function media_upload_header() {
2055
-	$post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2055
+    $post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2056 2056
 
2057
-	echo '<script type="text/javascript">post_id = ' . $post_id . ';</script>';
2057
+    echo '<script type="text/javascript">post_id = ' . $post_id . ';</script>';
2058 2058
 
2059
-	if ( empty( $_GET['chromeless'] ) ) {
2060
-		echo '<div id="media-upload-header">';
2061
-		the_media_upload_tabs();
2062
-		echo '</div>';
2063
-	}
2059
+    if ( empty( $_GET['chromeless'] ) ) {
2060
+        echo '<div id="media-upload-header">';
2061
+        the_media_upload_tabs();
2062
+        echo '</div>';
2063
+    }
2064 2064
 }
2065 2065
 
2066 2066
 /**
@@ -2076,156 +2076,156 @@  discard block
 block discarded – undo
2076 2076
  * @param array $errors
2077 2077
  */
2078 2078
 function media_upload_form( $errors = null ) {
2079
-	global $type, $tab, $is_IE, $is_opera;
2080
-
2081
-	if ( ! _device_can_upload() ) {
2082
-		echo '<p>' . sprintf(
2083
-			/* translators: %s: https://apps.wordpress.org/ */
2084
-			__( 'The web browser on your device cannot be used to upload files. You may be able to use the <a href="%s">native app for your device</a> instead.' ),
2085
-			'https://apps.wordpress.org/'
2086
-		) . '</p>';
2087
-		return;
2088
-	}
2089
-
2090
-	$upload_action_url = admin_url( 'async-upload.php' );
2091
-	$post_id           = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2092
-	$_type             = isset( $type ) ? $type : '';
2093
-	$_tab              = isset( $tab ) ? $tab : '';
2094
-
2095
-	$max_upload_size = wp_max_upload_size();
2096
-	if ( ! $max_upload_size ) {
2097
-		$max_upload_size = 0;
2098
-	}
2099
-
2100
-	?>
2079
+    global $type, $tab, $is_IE, $is_opera;
2080
+
2081
+    if ( ! _device_can_upload() ) {
2082
+        echo '<p>' . sprintf(
2083
+            /* translators: %s: https://apps.wordpress.org/ */
2084
+            __( 'The web browser on your device cannot be used to upload files. You may be able to use the <a href="%s">native app for your device</a> instead.' ),
2085
+            'https://apps.wordpress.org/'
2086
+        ) . '</p>';
2087
+        return;
2088
+    }
2089
+
2090
+    $upload_action_url = admin_url( 'async-upload.php' );
2091
+    $post_id           = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2092
+    $_type             = isset( $type ) ? $type : '';
2093
+    $_tab              = isset( $tab ) ? $tab : '';
2094
+
2095
+    $max_upload_size = wp_max_upload_size();
2096
+    if ( ! $max_upload_size ) {
2097
+        $max_upload_size = 0;
2098
+    }
2099
+
2100
+    ?>
2101 2101
 	<div id="media-upload-notice">
2102 2102
 	<?php
2103 2103
 
2104
-	if ( isset( $errors['upload_notice'] ) ) {
2105
-		echo $errors['upload_notice'];
2106
-	}
2104
+    if ( isset( $errors['upload_notice'] ) ) {
2105
+        echo $errors['upload_notice'];
2106
+    }
2107 2107
 
2108
-	?>
2108
+    ?>
2109 2109
 	</div>
2110 2110
 	<div id="media-upload-error">
2111 2111
 	<?php
2112 2112
 
2113
-	if ( isset( $errors['upload_error'] ) && is_wp_error( $errors['upload_error'] ) ) {
2114
-		echo $errors['upload_error']->get_error_message();
2115
-	}
2113
+    if ( isset( $errors['upload_error'] ) && is_wp_error( $errors['upload_error'] ) ) {
2114
+        echo $errors['upload_error']->get_error_message();
2115
+    }
2116 2116
 
2117
-	?>
2117
+    ?>
2118 2118
 	</div>
2119 2119
 	<?php
2120 2120
 
2121
-	if ( is_multisite() && ! is_upload_space_available() ) {
2122
-		/**
2123
-		 * Fires when an upload will exceed the defined upload space quota for a network site.
2124
-		 *
2125
-		 * @since 3.5.0
2126
-		 */
2127
-		do_action( 'upload_ui_over_quota' );
2128
-		return;
2129
-	}
2130
-
2131
-	/**
2132
-	 * Fires just before the legacy (pre-3.5.0) upload interface is loaded.
2133
-	 *
2134
-	 * @since 2.6.0
2135
-	 */
2136
-	do_action( 'pre-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2137
-
2138
-	$post_params = array(
2139
-		'post_id'  => $post_id,
2140
-		'_wpnonce' => wp_create_nonce( 'media-form' ),
2141
-		'type'     => $_type,
2142
-		'tab'      => $_tab,
2143
-		'short'    => '1',
2144
-	);
2145
-
2146
-	/**
2147
-	 * Filters the media upload post parameters.
2148
-	 *
2149
-	 * @since 3.1.0 As 'swfupload_post_params'
2150
-	 * @since 3.3.0
2151
-	 *
2152
-	 * @param array $post_params An array of media upload parameters used by Plupload.
2153
-	 */
2154
-	$post_params = apply_filters( 'upload_post_params', $post_params );
2155
-
2156
-	/*
2121
+    if ( is_multisite() && ! is_upload_space_available() ) {
2122
+        /**
2123
+         * Fires when an upload will exceed the defined upload space quota for a network site.
2124
+         *
2125
+         * @since 3.5.0
2126
+         */
2127
+        do_action( 'upload_ui_over_quota' );
2128
+        return;
2129
+    }
2130
+
2131
+    /**
2132
+     * Fires just before the legacy (pre-3.5.0) upload interface is loaded.
2133
+     *
2134
+     * @since 2.6.0
2135
+     */
2136
+    do_action( 'pre-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2137
+
2138
+    $post_params = array(
2139
+        'post_id'  => $post_id,
2140
+        '_wpnonce' => wp_create_nonce( 'media-form' ),
2141
+        'type'     => $_type,
2142
+        'tab'      => $_tab,
2143
+        'short'    => '1',
2144
+    );
2145
+
2146
+    /**
2147
+     * Filters the media upload post parameters.
2148
+     *
2149
+     * @since 3.1.0 As 'swfupload_post_params'
2150
+     * @since 3.3.0
2151
+     *
2152
+     * @param array $post_params An array of media upload parameters used by Plupload.
2153
+     */
2154
+    $post_params = apply_filters( 'upload_post_params', $post_params );
2155
+
2156
+    /*
2157 2157
 	* Since 4.9 the `runtimes` setting is hardcoded in our version of Plupload to `html5,html4`,
2158 2158
 	* and the `flash_swf_url` and `silverlight_xap_url` are not used.
2159 2159
 	*/
2160
-	$plupload_init = array(
2161
-		'browse_button'    => 'plupload-browse-button',
2162
-		'container'        => 'plupload-upload-ui',
2163
-		'drop_element'     => 'drag-drop-area',
2164
-		'file_data_name'   => 'async-upload',
2165
-		'url'              => $upload_action_url,
2166
-		'filters'          => array( 'max_file_size' => $max_upload_size . 'b' ),
2167
-		'multipart_params' => $post_params,
2168
-	);
2169
-
2170
-	/*
2160
+    $plupload_init = array(
2161
+        'browse_button'    => 'plupload-browse-button',
2162
+        'container'        => 'plupload-upload-ui',
2163
+        'drop_element'     => 'drag-drop-area',
2164
+        'file_data_name'   => 'async-upload',
2165
+        'url'              => $upload_action_url,
2166
+        'filters'          => array( 'max_file_size' => $max_upload_size . 'b' ),
2167
+        'multipart_params' => $post_params,
2168
+    );
2169
+
2170
+    /*
2171 2171
 	 * Currently only iOS Safari supports multiple files uploading,
2172 2172
 	 * but iOS 7.x has a bug that prevents uploading of videos when enabled.
2173 2173
 	 * See #29602.
2174 2174
 	 */
2175
-	if (
2176
-		wp_is_mobile() &&
2177
-		strpos( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) !== false &&
2178
-		strpos( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' ) !== false
2179
-	) {
2180
-		$plupload_init['multi_selection'] = false;
2181
-	}
2182
-
2183
-	// Check if WebP images can be edited.
2184
-	if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
2185
-		$plupload_init['webp_upload_error'] = true;
2186
-	}
2187
-
2188
-	/**
2189
-	 * Filters the default Plupload settings.
2190
-	 *
2191
-	 * @since 3.3.0
2192
-	 *
2193
-	 * @param array $plupload_init An array of default settings used by Plupload.
2194
-	 */
2195
-	$plupload_init = apply_filters( 'plupload_init', $plupload_init );
2196
-
2197
-	?>
2175
+    if (
2176
+        wp_is_mobile() &&
2177
+        strpos( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) !== false &&
2178
+        strpos( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' ) !== false
2179
+    ) {
2180
+        $plupload_init['multi_selection'] = false;
2181
+    }
2182
+
2183
+    // Check if WebP images can be edited.
2184
+    if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
2185
+        $plupload_init['webp_upload_error'] = true;
2186
+    }
2187
+
2188
+    /**
2189
+     * Filters the default Plupload settings.
2190
+     *
2191
+     * @since 3.3.0
2192
+     *
2193
+     * @param array $plupload_init An array of default settings used by Plupload.
2194
+     */
2195
+    $plupload_init = apply_filters( 'plupload_init', $plupload_init );
2196
+
2197
+    ?>
2198 2198
 	<script type="text/javascript">
2199 2199
 	<?php
2200
-	// Verify size is an int. If not return default value.
2201
-	$large_size_h = absint( get_option( 'large_size_h' ) );
2200
+    // Verify size is an int. If not return default value.
2201
+    $large_size_h = absint( get_option( 'large_size_h' ) );
2202 2202
 
2203
-	if ( ! $large_size_h ) {
2204
-		$large_size_h = 1024;
2205
-	}
2203
+    if ( ! $large_size_h ) {
2204
+        $large_size_h = 1024;
2205
+    }
2206 2206
 
2207
-	$large_size_w = absint( get_option( 'large_size_w' ) );
2207
+    $large_size_w = absint( get_option( 'large_size_w' ) );
2208 2208
 
2209
-	if ( ! $large_size_w ) {
2210
-		$large_size_w = 1024;
2211
-	}
2209
+    if ( ! $large_size_w ) {
2210
+        $large_size_w = 1024;
2211
+    }
2212 2212
 
2213
-	?>
2213
+    ?>
2214 2214
 	var resize_height = <?php echo $large_size_h; ?>, resize_width = <?php echo $large_size_w; ?>,
2215 2215
 	wpUploaderInit = <?php echo wp_json_encode( $plupload_init ); ?>;
2216 2216
 	</script>
2217 2217
 
2218 2218
 	<div id="plupload-upload-ui" class="hide-if-no-js">
2219 2219
 	<?php
2220
-	/**
2221
-	 * Fires before the upload interface loads.
2222
-	 *
2223
-	 * @since 2.6.0 As 'pre-flash-upload-ui'
2224
-	 * @since 3.3.0
2225
-	 */
2226
-	do_action( 'pre-plupload-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2227
-
2228
-	?>
2220
+    /**
2221
+     * Fires before the upload interface loads.
2222
+     *
2223
+     * @since 2.6.0 As 'pre-flash-upload-ui'
2224
+     * @since 3.3.0
2225
+     */
2226
+    do_action( 'pre-plupload-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2227
+
2228
+    ?>
2229 2229
 	<div id="drag-drop-area">
2230 2230
 		<div class="drag-drop-inside">
2231 2231
 		<p class="drag-drop-info"><?php _e( 'Drop files to upload' ); ?></p>
@@ -2234,26 +2234,26 @@  discard block
 block discarded – undo
2234 2234
 		</div>
2235 2235
 	</div>
2236 2236
 	<?php
2237
-	/**
2238
-	 * Fires after the upload interface loads.
2239
-	 *
2240
-	 * @since 2.6.0 As 'post-flash-upload-ui'
2241
-	 * @since 3.3.0
2242
-	 */
2243
-	do_action( 'post-plupload-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2244
-	?>
2237
+    /**
2238
+     * Fires after the upload interface loads.
2239
+     *
2240
+     * @since 2.6.0 As 'post-flash-upload-ui'
2241
+     * @since 3.3.0
2242
+     */
2243
+    do_action( 'post-plupload-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2244
+    ?>
2245 2245
 	</div>
2246 2246
 
2247 2247
 	<div id="html-upload-ui" class="hide-if-js">
2248 2248
 	<?php
2249
-	/**
2250
-	 * Fires before the upload button in the media upload interface.
2251
-	 *
2252
-	 * @since 2.6.0
2253
-	 */
2254
-	do_action( 'pre-html-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2255
-
2256
-	?>
2249
+    /**
2250
+     * Fires before the upload button in the media upload interface.
2251
+     *
2252
+     * @since 2.6.0
2253
+     */
2254
+    do_action( 'pre-html-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2255
+
2256
+    ?>
2257 2257
 	<p id="async-upload-wrap">
2258 2258
 		<label class="screen-reader-text" for="async-upload"><?php _e( 'Upload' ); ?></label>
2259 2259
 		<input type="file" name="async-upload" id="async-upload" />
@@ -2262,32 +2262,32 @@  discard block
 block discarded – undo
2262 2262
 	</p>
2263 2263
 	<div class="clear"></div>
2264 2264
 	<?php
2265
-	/**
2266
-	 * Fires after the upload button in the media upload interface.
2267
-	 *
2268
-	 * @since 2.6.0
2269
-	 */
2270
-	do_action( 'post-html-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2271
-
2272
-	?>
2265
+    /**
2266
+     * Fires after the upload button in the media upload interface.
2267
+     *
2268
+     * @since 2.6.0
2269
+     */
2270
+    do_action( 'post-html-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2271
+
2272
+    ?>
2273 2273
 	</div>
2274 2274
 
2275 2275
 <p class="max-upload-size">
2276 2276
 	<?php
2277
-	/* translators: %s: Maximum allowed file size. */
2278
-	printf( __( 'Maximum upload file size: %s.' ), esc_html( size_format( $max_upload_size ) ) );
2279
-	?>
2277
+    /* translators: %s: Maximum allowed file size. */
2278
+    printf( __( 'Maximum upload file size: %s.' ), esc_html( size_format( $max_upload_size ) ) );
2279
+    ?>
2280 2280
 </p>
2281 2281
 	<?php
2282 2282
 
2283
-	/**
2284
-	 * Fires on the post upload UI screen.
2285
-	 *
2286
-	 * Legacy (pre-3.5.0) media workflow hook.
2287
-	 *
2288
-	 * @since 2.6.0
2289
-	 */
2290
-	do_action( 'post-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2283
+    /**
2284
+     * Fires on the post upload UI screen.
2285
+     *
2286
+     * Legacy (pre-3.5.0) media workflow hook.
2287
+     *
2288
+     * @since 2.6.0
2289
+     */
2290
+    do_action( 'post-upload-ui' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
2291 2291
 }
2292 2292
 
2293 2293
 /**
@@ -2301,28 +2301,28 @@  discard block
 block discarded – undo
2301 2301
  */
2302 2302
 function media_upload_type_form( $type = 'file', $errors = null, $id = null ) {
2303 2303
 
2304
-	media_upload_header();
2304
+    media_upload_header();
2305 2305
 
2306
-	$post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2306
+    $post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2307 2307
 
2308
-	$form_action_url = admin_url( "media-upload.php?type=$type&tab=type&post_id=$post_id" );
2308
+    $form_action_url = admin_url( "media-upload.php?type=$type&tab=type&post_id=$post_id" );
2309 2309
 
2310
-	/**
2311
-	 * Filters the media upload form action URL.
2312
-	 *
2313
-	 * @since 2.6.0
2314
-	 *
2315
-	 * @param string $form_action_url The media upload form action URL.
2316
-	 * @param string $type            The type of media. Default 'file'.
2317
-	 */
2318
-	$form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2319
-	$form_class      = 'media-upload-form type-form validate';
2310
+    /**
2311
+     * Filters the media upload form action URL.
2312
+     *
2313
+     * @since 2.6.0
2314
+     *
2315
+     * @param string $form_action_url The media upload form action URL.
2316
+     * @param string $type            The type of media. Default 'file'.
2317
+     */
2318
+    $form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2319
+    $form_class      = 'media-upload-form type-form validate';
2320 2320
 
2321
-	if ( get_user_setting( 'uploader' ) ) {
2322
-		$form_class .= ' html-uploader';
2323
-	}
2321
+    if ( get_user_setting( 'uploader' ) ) {
2322
+        $form_class .= ' html-uploader';
2323
+    }
2324 2324
 
2325
-	?>
2325
+    ?>
2326 2326
 	<form enctype="multipart/form-data" method="post" action="<?php echo esc_url( $form_action_url ); ?>" class="<?php echo $form_class; ?>" id="<?php echo $type; ?>-form">
2327 2327
 		<?php submit_button( '', 'hidden', 'save', false ); ?>
2328 2328
 	<input type="hidden" name="post_id" id="post_id" value="<?php echo (int) $post_id; ?>" />
@@ -2344,17 +2344,17 @@  discard block
 block discarded – undo
2344 2344
 	<div id="media-items">
2345 2345
 	<?php
2346 2346
 
2347
-	if ( $id ) {
2348
-		if ( ! is_wp_error( $id ) ) {
2349
-			add_filter( 'attachment_fields_to_edit', 'media_post_single_attachment_fields_to_edit', 10, 2 );
2350
-			echo get_media_items( $id, $errors );
2351
-		} else {
2352
-			echo '<div id="media-upload-error">' . esc_html( $id->get_error_message() ) . '</div></div>';
2353
-			exit;
2354
-		}
2355
-	}
2356
-
2357
-	?>
2347
+    if ( $id ) {
2348
+        if ( ! is_wp_error( $id ) ) {
2349
+            add_filter( 'attachment_fields_to_edit', 'media_post_single_attachment_fields_to_edit', 10, 2 );
2350
+            echo get_media_items( $id, $errors );
2351
+        } else {
2352
+            echo '<div id="media-upload-error">' . esc_html( $id->get_error_message() ) . '</div></div>';
2353
+            exit;
2354
+        }
2355
+    }
2356
+
2357
+    ?>
2358 2358
 	</div>
2359 2359
 
2360 2360
 	<p class="savebutton ml-submit">
@@ -2374,24 +2374,24 @@  discard block
 block discarded – undo
2374 2374
  * @param int     $id
2375 2375
  */
2376 2376
 function media_upload_type_url_form( $type = null, $errors = null, $id = null ) {
2377
-	if ( null === $type ) {
2378
-		$type = 'image';
2379
-	}
2377
+    if ( null === $type ) {
2378
+        $type = 'image';
2379
+    }
2380 2380
 
2381
-	media_upload_header();
2381
+    media_upload_header();
2382 2382
 
2383
-	$post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2383
+    $post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2384 2384
 
2385
-	$form_action_url = admin_url( "media-upload.php?type=$type&tab=type&post_id=$post_id" );
2386
-	/** This filter is documented in wp-admin/includes/media.php */
2387
-	$form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2388
-	$form_class      = 'media-upload-form type-form validate';
2385
+    $form_action_url = admin_url( "media-upload.php?type=$type&tab=type&post_id=$post_id" );
2386
+    /** This filter is documented in wp-admin/includes/media.php */
2387
+    $form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2388
+    $form_class      = 'media-upload-form type-form validate';
2389 2389
 
2390
-	if ( get_user_setting( 'uploader' ) ) {
2391
-		$form_class .= ' html-uploader';
2392
-	}
2390
+    if ( get_user_setting( 'uploader' ) ) {
2391
+        $form_class .= ' html-uploader';
2392
+    }
2393 2393
 
2394
-	?>
2394
+    ?>
2395 2395
 	<form enctype="multipart/form-data" method="post" action="<?php echo esc_url( $form_action_url ); ?>" class="<?php echo $form_class; ?>" id="<?php echo $type; ?>-form">
2396 2396
 	<input type="hidden" name="post_id" id="post_id" value="<?php echo (int) $post_id; ?>" />
2397 2397
 		<?php wp_nonce_field( 'media-form' ); ?>
@@ -2415,9 +2415,9 @@  discard block
 block discarded – undo
2415 2415
 			alt = f.alt.value.replace(/'/g, '&#039;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
2416 2416
 
2417 2417
 		<?php
2418
-		/** This filter is documented in wp-admin/includes/media.php */
2419
-		if ( ! apply_filters( 'disable_captions', '' ) ) {
2420
-			?>
2418
+        /** This filter is documented in wp-admin/includes/media.php */
2419
+        if ( ! apply_filters( 'disable_captions', '' ) ) {
2420
+            ?>
2421 2421
 			if ( f.caption.value ) {
2422 2422
 				caption = f.caption.value.replace(/\r\n|\r/g, '\n');
2423 2423
 				caption = caption.replace(/<[a-zA-Z0-9]+( [^<>]+)?>/g, function(a){
@@ -2427,9 +2427,9 @@  discard block
 block discarded – undo
2427 2427
 				caption = caption.replace(/\s*\n\s*/g, '<br />');
2428 2428
 			}
2429 2429
 			<?php
2430
-		}
2430
+        }
2431 2431
 
2432
-		?>
2432
+        ?>
2433 2433
 		cls = caption ? '' : ' class="'+t.align+'"';
2434 2434
 
2435 2435
 		html = '<img alt="'+alt+'" src="'+f.src.value+'"'+cls+' width="'+t.width+'" height="'+t.height+'" />';
@@ -2495,16 +2495,16 @@  discard block
 block discarded – undo
2495 2495
 	<div id="media-items">
2496 2496
 	<div class="media-item media-blank">
2497 2497
 	<?php
2498
-	/**
2499
-	 * Filters the insert media from URL form HTML.
2500
-	 *
2501
-	 * @since 3.3.0
2502
-	 *
2503
-	 * @param string $form_html The insert from URL form HTML.
2504
-	 */
2505
-	echo apply_filters( 'type_url_form_media', wp_media_insert_url_form( $type ) );
2506
-
2507
-	?>
2498
+    /**
2499
+     * Filters the insert media from URL form HTML.
2500
+     *
2501
+     * @since 3.3.0
2502
+     *
2503
+     * @param string $form_html The insert from URL form HTML.
2504
+     */
2505
+    echo apply_filters( 'type_url_form_media', wp_media_insert_url_form( $type ) );
2506
+
2507
+    ?>
2508 2508
 	</div>
2509 2509
 	</div>
2510 2510
 	</form>
@@ -2523,22 +2523,22 @@  discard block
 block discarded – undo
2523 2523
  * @param array $errors
2524 2524
  */
2525 2525
 function media_upload_gallery_form( $errors ) {
2526
-	global $redir_tab, $type;
2526
+    global $redir_tab, $type;
2527 2527
 
2528
-	$redir_tab = 'gallery';
2529
-	media_upload_header();
2528
+    $redir_tab = 'gallery';
2529
+    media_upload_header();
2530 2530
 
2531
-	$post_id         = (int) $_REQUEST['post_id'];
2532
-	$form_action_url = admin_url( "media-upload.php?type=$type&tab=gallery&post_id=$post_id" );
2533
-	/** This filter is documented in wp-admin/includes/media.php */
2534
-	$form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2535
-	$form_class      = 'media-upload-form validate';
2531
+    $post_id         = (int) $_REQUEST['post_id'];
2532
+    $form_action_url = admin_url( "media-upload.php?type=$type&tab=gallery&post_id=$post_id" );
2533
+    /** This filter is documented in wp-admin/includes/media.php */
2534
+    $form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2535
+    $form_class      = 'media-upload-form validate';
2536 2536
 
2537
-	if ( get_user_setting( 'uploader' ) ) {
2538
-		$form_class .= ' html-uploader';
2539
-	}
2537
+    if ( get_user_setting( 'uploader' ) ) {
2538
+        $form_class .= ' html-uploader';
2539
+    }
2540 2540
 
2541
-	?>
2541
+    ?>
2542 2542
 	<script type="text/javascript">
2543 2543
 	jQuery(function($){
2544 2544
 		var preloaded = $(".media-item.preloaded");
@@ -2575,17 +2575,17 @@  discard block
 block discarded – undo
2575 2575
 
2576 2576
 	<p class="ml-submit">
2577 2577
 		<?php
2578
-		submit_button(
2579
-			__( 'Save all changes' ),
2580
-			'savebutton',
2581
-			'save',
2582
-			false,
2583
-			array(
2584
-				'id'    => 'save-all',
2585
-				'style' => 'display: none;',
2586
-			)
2587
-		);
2588
-		?>
2578
+        submit_button(
2579
+            __( 'Save all changes' ),
2580
+            'savebutton',
2581
+            'save',
2582
+            false,
2583
+            array(
2584
+                'id'    => 'save-all',
2585
+                'style' => 'display: none;',
2586
+            )
2587
+        );
2588
+        ?>
2589 2589
 	<input type="hidden" name="post_id" id="post_id" value="<?php echo (int) $post_id; ?>" />
2590 2590
 	<input type="hidden" name="type" value="<?php echo esc_attr( $GLOBALS['type'] ); ?>" />
2591 2591
 	<input type="hidden" name="tab" value="<?php echo esc_attr( $GLOBALS['tab'] ); ?>" />
@@ -2686,35 +2686,35 @@  discard block
 block discarded – undo
2686 2686
  * @param array $errors
2687 2687
  */
2688 2688
 function media_upload_library_form( $errors ) {
2689
-	global $wpdb, $wp_query, $wp_locale, $type, $tab, $post_mime_types;
2689
+    global $wpdb, $wp_query, $wp_locale, $type, $tab, $post_mime_types;
2690 2690
 
2691
-	media_upload_header();
2691
+    media_upload_header();
2692 2692
 
2693
-	$post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2693
+    $post_id = isset( $_REQUEST['post_id'] ) ? (int) $_REQUEST['post_id'] : 0;
2694 2694
 
2695
-	$form_action_url = admin_url( "media-upload.php?type=$type&tab=library&post_id=$post_id" );
2696
-	/** This filter is documented in wp-admin/includes/media.php */
2697
-	$form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2698
-	$form_class      = 'media-upload-form validate';
2695
+    $form_action_url = admin_url( "media-upload.php?type=$type&tab=library&post_id=$post_id" );
2696
+    /** This filter is documented in wp-admin/includes/media.php */
2697
+    $form_action_url = apply_filters( 'media_upload_form_url', $form_action_url, $type );
2698
+    $form_class      = 'media-upload-form validate';
2699 2699
 
2700
-	if ( get_user_setting( 'uploader' ) ) {
2701
-		$form_class .= ' html-uploader';
2702
-	}
2700
+    if ( get_user_setting( 'uploader' ) ) {
2701
+        $form_class .= ' html-uploader';
2702
+    }
2703 2703
 
2704
-	$q                   = $_GET;
2705
-	$q['posts_per_page'] = 10;
2706
-	$q['paged']          = isset( $q['paged'] ) ? (int) $q['paged'] : 0;
2707
-	if ( $q['paged'] < 1 ) {
2708
-		$q['paged'] = 1;
2709
-	}
2710
-	$q['offset'] = ( $q['paged'] - 1 ) * 10;
2711
-	if ( $q['offset'] < 1 ) {
2712
-		$q['offset'] = 0;
2713
-	}
2704
+    $q                   = $_GET;
2705
+    $q['posts_per_page'] = 10;
2706
+    $q['paged']          = isset( $q['paged'] ) ? (int) $q['paged'] : 0;
2707
+    if ( $q['paged'] < 1 ) {
2708
+        $q['paged'] = 1;
2709
+    }
2710
+    $q['offset'] = ( $q['paged'] - 1 ) * 10;
2711
+    if ( $q['offset'] < 1 ) {
2712
+        $q['offset'] = 0;
2713
+    }
2714 2714
 
2715
-	list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query( $q );
2715
+    list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query( $q );
2716 2716
 
2717
-	?>
2717
+    ?>
2718 2718
 	<form id="filter" method="get">
2719 2719
 	<input type="hidden" name="type" value="<?php echo esc_attr( $type ); ?>" />
2720 2720
 	<input type="hidden" name="tab" value="<?php echo esc_attr( $tab ); ?>" />
@@ -2730,125 +2730,125 @@  discard block
 block discarded – undo
2730 2730
 
2731 2731
 	<ul class="subsubsub">
2732 2732
 		<?php
2733
-		$type_links = array();
2734
-		$_num_posts = (array) wp_count_attachments();
2735
-		$matches    = wp_match_mime_types( array_keys( $post_mime_types ), array_keys( $_num_posts ) );
2736
-		foreach ( $matches as $_type => $reals ) {
2737
-			foreach ( $reals as $real ) {
2738
-				if ( isset( $num_posts[ $_type ] ) ) {
2739
-					$num_posts[ $_type ] += $_num_posts[ $real ];
2740
-				} else {
2741
-					$num_posts[ $_type ] = $_num_posts[ $real ];
2742
-				}
2743
-			}
2744
-		}
2745
-		// If available type specified by media button clicked, filter by that type.
2746
-		if ( empty( $_GET['post_mime_type'] ) && ! empty( $num_posts[ $type ] ) ) {
2747
-			$_GET['post_mime_type']                        = $type;
2748
-			list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query();
2749
-		}
2750
-		if ( empty( $_GET['post_mime_type'] ) || 'all' === $_GET['post_mime_type'] ) {
2751
-			$class = ' class="current"';
2752
-		} else {
2753
-			$class = '';
2754
-		}
2755
-		$type_links[] = '<li><a href="' . esc_url(
2756
-			add_query_arg(
2757
-				array(
2758
-					'post_mime_type' => 'all',
2759
-					'paged'          => false,
2760
-					'm'              => false,
2761
-				)
2762
-			)
2763
-		) . '"' . $class . '>' . __( 'All Types' ) . '</a>';
2764
-		foreach ( $post_mime_types as $mime_type => $label ) {
2765
-			$class = '';
2766
-
2767
-			if ( ! wp_match_mime_types( $mime_type, $avail_post_mime_types ) ) {
2768
-				continue;
2769
-			}
2770
-
2771
-			if ( isset( $_GET['post_mime_type'] ) && wp_match_mime_types( $mime_type, $_GET['post_mime_type'] ) ) {
2772
-				$class = ' class="current"';
2773
-			}
2774
-
2775
-			$type_links[] = '<li><a href="' . esc_url(
2776
-				add_query_arg(
2777
-					array(
2778
-						'post_mime_type' => $mime_type,
2779
-						'paged'          => false,
2780
-					)
2781
-				)
2782
-			) . '"' . $class . '>' . sprintf( translate_nooped_plural( $label[2], $num_posts[ $mime_type ] ), '<span id="' . $mime_type . '-counter">' . number_format_i18n( $num_posts[ $mime_type ] ) . '</span>' ) . '</a>';
2783
-		}
2784
-		/**
2785
-		 * Filters the media upload mime type list items.
2786
-		 *
2787
-		 * Returned values should begin with an `<li>` tag.
2788
-		 *
2789
-		 * @since 3.1.0
2790
-		 *
2791
-		 * @param string[] $type_links An array of list items containing mime type link HTML.
2792
-		 */
2793
-		echo implode( ' | </li>', apply_filters( 'media_upload_mime_type_links', $type_links ) ) . '</li>';
2794
-		unset( $type_links );
2795
-		?>
2733
+        $type_links = array();
2734
+        $_num_posts = (array) wp_count_attachments();
2735
+        $matches    = wp_match_mime_types( array_keys( $post_mime_types ), array_keys( $_num_posts ) );
2736
+        foreach ( $matches as $_type => $reals ) {
2737
+            foreach ( $reals as $real ) {
2738
+                if ( isset( $num_posts[ $_type ] ) ) {
2739
+                    $num_posts[ $_type ] += $_num_posts[ $real ];
2740
+                } else {
2741
+                    $num_posts[ $_type ] = $_num_posts[ $real ];
2742
+                }
2743
+            }
2744
+        }
2745
+        // If available type specified by media button clicked, filter by that type.
2746
+        if ( empty( $_GET['post_mime_type'] ) && ! empty( $num_posts[ $type ] ) ) {
2747
+            $_GET['post_mime_type']                        = $type;
2748
+            list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query();
2749
+        }
2750
+        if ( empty( $_GET['post_mime_type'] ) || 'all' === $_GET['post_mime_type'] ) {
2751
+            $class = ' class="current"';
2752
+        } else {
2753
+            $class = '';
2754
+        }
2755
+        $type_links[] = '<li><a href="' . esc_url(
2756
+            add_query_arg(
2757
+                array(
2758
+                    'post_mime_type' => 'all',
2759
+                    'paged'          => false,
2760
+                    'm'              => false,
2761
+                )
2762
+            )
2763
+        ) . '"' . $class . '>' . __( 'All Types' ) . '</a>';
2764
+        foreach ( $post_mime_types as $mime_type => $label ) {
2765
+            $class = '';
2766
+
2767
+            if ( ! wp_match_mime_types( $mime_type, $avail_post_mime_types ) ) {
2768
+                continue;
2769
+            }
2770
+
2771
+            if ( isset( $_GET['post_mime_type'] ) && wp_match_mime_types( $mime_type, $_GET['post_mime_type'] ) ) {
2772
+                $class = ' class="current"';
2773
+            }
2774
+
2775
+            $type_links[] = '<li><a href="' . esc_url(
2776
+                add_query_arg(
2777
+                    array(
2778
+                        'post_mime_type' => $mime_type,
2779
+                        'paged'          => false,
2780
+                    )
2781
+                )
2782
+            ) . '"' . $class . '>' . sprintf( translate_nooped_plural( $label[2], $num_posts[ $mime_type ] ), '<span id="' . $mime_type . '-counter">' . number_format_i18n( $num_posts[ $mime_type ] ) . '</span>' ) . '</a>';
2783
+        }
2784
+        /**
2785
+         * Filters the media upload mime type list items.
2786
+         *
2787
+         * Returned values should begin with an `<li>` tag.
2788
+         *
2789
+         * @since 3.1.0
2790
+         *
2791
+         * @param string[] $type_links An array of list items containing mime type link HTML.
2792
+         */
2793
+        echo implode( ' | </li>', apply_filters( 'media_upload_mime_type_links', $type_links ) ) . '</li>';
2794
+        unset( $type_links );
2795
+        ?>
2796 2796
 	</ul>
2797 2797
 
2798 2798
 	<div class="tablenav">
2799 2799
 
2800 2800
 		<?php
2801
-		$page_links = paginate_links(
2802
-			array(
2803
-				'base'      => add_query_arg( 'paged', '%#%' ),
2804
-				'format'    => '',
2805
-				'prev_text' => __( '&laquo;' ),
2806
-				'next_text' => __( '&raquo;' ),
2807
-				'total'     => ceil( $wp_query->found_posts / 10 ),
2808
-				'current'   => $q['paged'],
2809
-			)
2810
-		);
2811
-
2812
-		if ( $page_links ) {
2813
-			echo "<div class='tablenav-pages'>$page_links</div>";
2814
-		}
2815
-		?>
2801
+        $page_links = paginate_links(
2802
+            array(
2803
+                'base'      => add_query_arg( 'paged', '%#%' ),
2804
+                'format'    => '',
2805
+                'prev_text' => __( '&laquo;' ),
2806
+                'next_text' => __( '&raquo;' ),
2807
+                'total'     => ceil( $wp_query->found_posts / 10 ),
2808
+                'current'   => $q['paged'],
2809
+            )
2810
+        );
2811
+
2812
+        if ( $page_links ) {
2813
+            echo "<div class='tablenav-pages'>$page_links</div>";
2814
+        }
2815
+        ?>
2816 2816
 
2817 2817
 	<div class="alignleft actions">
2818 2818
 		<?php
2819 2819
 
2820
-		$arc_query = "SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = 'attachment' ORDER BY post_date DESC";
2820
+        $arc_query = "SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = 'attachment' ORDER BY post_date DESC";
2821 2821
 
2822
-		$arc_result = $wpdb->get_results( $arc_query );
2822
+        $arc_result = $wpdb->get_results( $arc_query );
2823 2823
 
2824
-		$month_count    = count( $arc_result );
2825
-		$selected_month = isset( $_GET['m'] ) ? $_GET['m'] : 0;
2824
+        $month_count    = count( $arc_result );
2825
+        $selected_month = isset( $_GET['m'] ) ? $_GET['m'] : 0;
2826 2826
 
2827
-		if ( $month_count && ! ( 1 == $month_count && 0 == $arc_result[0]->mmonth ) ) {
2828
-			?>
2827
+        if ( $month_count && ! ( 1 == $month_count && 0 == $arc_result[0]->mmonth ) ) {
2828
+            ?>
2829 2829
 			<select name='m'>
2830 2830
 			<option<?php selected( $selected_month, 0 ); ?> value='0'><?php _e( 'All dates' ); ?></option>
2831 2831
 			<?php
2832 2832
 
2833
-			foreach ( $arc_result as $arc_row ) {
2834
-				if ( 0 == $arc_row->yyear ) {
2835
-					continue;
2836
-				}
2833
+            foreach ( $arc_result as $arc_row ) {
2834
+                if ( 0 == $arc_row->yyear ) {
2835
+                    continue;
2836
+                }
2837 2837
 
2838
-				$arc_row->mmonth = zeroise( $arc_row->mmonth, 2 );
2838
+                $arc_row->mmonth = zeroise( $arc_row->mmonth, 2 );
2839 2839
 
2840
-				if ( $arc_row->yyear . $arc_row->mmonth == $selected_month ) {
2841
-					$default = ' selected="selected"';
2842
-				} else {
2843
-					$default = '';
2844
-				}
2840
+                if ( $arc_row->yyear . $arc_row->mmonth == $selected_month ) {
2841
+                    $default = ' selected="selected"';
2842
+                } else {
2843
+                    $default = '';
2844
+                }
2845 2845
 
2846
-				echo "<option$default value='" . esc_attr( $arc_row->yyear . $arc_row->mmonth ) . "'>";
2847
-				echo esc_html( $wp_locale->get_month( $arc_row->mmonth ) . " $arc_row->yyear" );
2848
-				echo "</option>\n";
2849
-			}
2846
+                echo "<option$default value='" . esc_attr( $arc_row->yyear . $arc_row->mmonth ) . "'>";
2847
+                echo esc_html( $wp_locale->get_month( $arc_row->mmonth ) . " $arc_row->yyear" );
2848
+                echo "</option>\n";
2849
+            }
2850 2850
 
2851
-			?>
2851
+            ?>
2852 2852
 			</select>
2853 2853
 		<?php } ?>
2854 2854
 
@@ -2894,39 +2894,39 @@  discard block
 block discarded – undo
2894 2894
  * @return string HTML content of the form.
2895 2895
  */
2896 2896
 function wp_media_insert_url_form( $default_view = 'image' ) {
2897
-	/** This filter is documented in wp-admin/includes/media.php */
2898
-	if ( ! apply_filters( 'disable_captions', '' ) ) {
2899
-		$caption = '
2897
+    /** This filter is documented in wp-admin/includes/media.php */
2898
+    if ( ! apply_filters( 'disable_captions', '' ) ) {
2899
+        $caption = '
2900 2900
 		<tr class="image-only">
2901 2901
 			<th scope="row" class="label">
2902 2902
 				<label for="caption"><span class="alignleft">' . __( 'Image Caption' ) . '</span></label>
2903 2903
 			</th>
2904 2904
 			<td class="field"><textarea id="caption" name="caption"></textarea></td>
2905 2905
 		</tr>';
2906
-	} else {
2907
-		$caption = '';
2908
-	}
2906
+    } else {
2907
+        $caption = '';
2908
+    }
2909 2909
 
2910
-	$default_align = get_option( 'image_default_align' );
2910
+    $default_align = get_option( 'image_default_align' );
2911 2911
 
2912
-	if ( empty( $default_align ) ) {
2913
-		$default_align = 'none';
2914
-	}
2912
+    if ( empty( $default_align ) ) {
2913
+        $default_align = 'none';
2914
+    }
2915 2915
 
2916
-	if ( 'image' === $default_view ) {
2917
-		$view        = 'image-only';
2918
-		$table_class = '';
2919
-	} else {
2920
-		$view        = 'not-image';
2921
-		$table_class = $view;
2922
-	}
2916
+    if ( 'image' === $default_view ) {
2917
+        $view        = 'image-only';
2918
+        $table_class = '';
2919
+    } else {
2920
+        $view        = 'not-image';
2921
+        $table_class = $view;
2922
+    }
2923 2923
 
2924
-	return '
2924
+    return '
2925 2925
 	<p class="media-types"><label><input type="radio" name="media_type" value="image" id="image-only"' . checked( 'image-only', $view, false ) . ' /> ' . __( 'Image' ) . '</label> &nbsp; &nbsp; <label><input type="radio" name="media_type" value="generic" id="not-image"' . checked( 'not-image', $view, false ) . ' /> ' . __( 'Audio, Video, or Other File' ) . '</label></p>
2926 2926
 	<p class="media-types media-types-required-info">' .
2927
-		/* translators: %s: Asterisk symbol (*). */
2928
-		sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
2929
-	'</p>
2927
+        /* translators: %s: Asterisk symbol (*). */
2928
+        sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
2929
+    '</p>
2930 2930
 	<table class="describe ' . $table_class . '"><tbody>
2931 2931
 		<tr>
2932 2932
 			<th scope="row" class="label" style="width:130px;">
@@ -3000,25 +3000,25 @@  discard block
 block discarded – undo
3000 3000
  * @global int $post_ID
3001 3001
  */
3002 3002
 function media_upload_flash_bypass() {
3003
-	$browser_uploader = admin_url( 'media-new.php?browser-uploader' );
3003
+    $browser_uploader = admin_url( 'media-new.php?browser-uploader' );
3004 3004
 
3005
-	$post = get_post();
3006
-	if ( $post ) {
3007
-		$browser_uploader .= '&amp;post_id=' . (int) $post->ID;
3008
-	} elseif ( ! empty( $GLOBALS['post_ID'] ) ) {
3009
-		$browser_uploader .= '&amp;post_id=' . (int) $GLOBALS['post_ID'];
3010
-	}
3005
+    $post = get_post();
3006
+    if ( $post ) {
3007
+        $browser_uploader .= '&amp;post_id=' . (int) $post->ID;
3008
+    } elseif ( ! empty( $GLOBALS['post_ID'] ) ) {
3009
+        $browser_uploader .= '&amp;post_id=' . (int) $GLOBALS['post_ID'];
3010
+    }
3011 3011
 
3012
-	?>
3012
+    ?>
3013 3013
 	<p class="upload-flash-bypass">
3014 3014
 	<?php
3015
-		printf(
3016
-			/* translators: 1: URL to browser uploader, 2: Additional link attributes. */
3017
-			__( 'You are using the multi-file uploader. Problems? Try the <a href="%1$s" %2$s>browser uploader</a> instead.' ),
3018
-			$browser_uploader,
3019
-			'target="_blank"'
3020
-		);
3021
-	?>
3015
+        printf(
3016
+            /* translators: 1: URL to browser uploader, 2: Additional link attributes. */
3017
+            __( 'You are using the multi-file uploader. Problems? Try the <a href="%1$s" %2$s>browser uploader</a> instead.' ),
3018
+            $browser_uploader,
3019
+            'target="_blank"'
3020
+        );
3021
+    ?>
3022 3022
 	</p>
3023 3023
 	<?php
3024 3024
 }
@@ -3029,7 +3029,7 @@  discard block
 block discarded – undo
3029 3029
  * @since 2.6.0
3030 3030
  */
3031 3031
 function media_upload_html_bypass() {
3032
-	?>
3032
+    ?>
3033 3033
 	<p class="upload-html-bypass hide-if-no-js">
3034 3034
 		<?php _e( 'You are using the browser&#8217;s built-in file uploader. The WordPress uploader includes multiple file selection and drag and drop capability. <a href="#">Switch to the multi-file uploader</a>.' ); ?>
3035 3035
 	</p>
@@ -3049,23 +3049,23 @@  discard block
 block discarded – undo
3049 3049
  * @since 3.3.0
3050 3050
  */
3051 3051
 function media_upload_max_image_resize() {
3052
-	$checked = get_user_setting( 'upload_resize' ) ? ' checked="true"' : '';
3053
-	$a       = '';
3054
-	$end     = '';
3052
+    $checked = get_user_setting( 'upload_resize' ) ? ' checked="true"' : '';
3053
+    $a       = '';
3054
+    $end     = '';
3055 3055
 
3056
-	if ( current_user_can( 'manage_options' ) ) {
3057
-		$a   = '<a href="' . esc_url( admin_url( 'options-media.php' ) ) . '" target="_blank">';
3058
-		$end = '</a>';
3059
-	}
3056
+    if ( current_user_can( 'manage_options' ) ) {
3057
+        $a   = '<a href="' . esc_url( admin_url( 'options-media.php' ) ) . '" target="_blank">';
3058
+        $end = '</a>';
3059
+    }
3060 3060
 
3061
-	?>
3061
+    ?>
3062 3062
 	<p class="hide-if-no-js"><label>
3063 3063
 	<input name="image_resize" type="checkbox" id="image_resize" value="true"<?php echo $checked; ?> />
3064 3064
 	<?php
3065
-	/* translators: 1: Link start tag, 2: Link end tag, 3: Width, 4: Height. */
3066
-	printf( __( 'Scale images to match the large size selected in %1$simage options%2$s (%3$d &times; %4$d).' ), $a, $end, (int) get_option( 'large_size_w', '1024' ), (int) get_option( 'large_size_h', '1024' ) );
3065
+    /* translators: 1: Link start tag, 2: Link end tag, 3: Width, 4: Height. */
3066
+    printf( __( 'Scale images to match the large size selected in %1$simage options%2$s (%3$d &times; %4$d).' ), $a, $end, (int) get_option( 'large_size_w', '1024' ), (int) get_option( 'large_size_h', '1024' ) );
3067 3067
 
3068
-	?>
3068
+    ?>
3069 3069
 	</label></p>
3070 3070
 	<?php
3071 3071
 }
@@ -3076,11 +3076,11 @@  discard block
 block discarded – undo
3076 3076
  * @since 3.5.0
3077 3077
  */
3078 3078
 function multisite_over_quota_message() {
3079
-	echo '<p>' . sprintf(
3080
-		/* translators: %s: Allowed space allocation. */
3081
-		__( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
3082
-		size_format( get_space_allowed() * MB_IN_BYTES )
3083
-	) . '</p>';
3079
+    echo '<p>' . sprintf(
3080
+        /* translators: %s: Allowed space allocation. */
3081
+        __( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
3082
+        size_format( get_space_allowed() * MB_IN_BYTES )
3083
+    ) . '</p>';
3084 3084
 }
3085 3085
 
3086 3086
 /**
@@ -3091,43 +3091,43 @@  discard block
 block discarded – undo
3091 3091
  * @param WP_Post $post A post object.
3092 3092
  */
3093 3093
 function edit_form_image_editor( $post ) {
3094
-	$open = isset( $_GET['image-editor'] );
3094
+    $open = isset( $_GET['image-editor'] );
3095 3095
 
3096
-	if ( $open ) {
3097
-		require_once ABSPATH . 'wp-admin/includes/image-edit.php';
3098
-	}
3096
+    if ( $open ) {
3097
+        require_once ABSPATH . 'wp-admin/includes/image-edit.php';
3098
+    }
3099 3099
 
3100
-	$thumb_url     = false;
3101
-	$attachment_id = (int) $post->ID;
3100
+    $thumb_url     = false;
3101
+    $attachment_id = (int) $post->ID;
3102 3102
 
3103
-	if ( $attachment_id ) {
3104
-		$thumb_url = wp_get_attachment_image_src( $attachment_id, array( 900, 450 ), true );
3105
-	}
3103
+    if ( $attachment_id ) {
3104
+        $thumb_url = wp_get_attachment_image_src( $attachment_id, array( 900, 450 ), true );
3105
+    }
3106 3106
 
3107
-	$alt_text = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
3107
+    $alt_text = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
3108 3108
 
3109
-	$att_url = wp_get_attachment_url( $post->ID );
3110
-	?>
3109
+    $att_url = wp_get_attachment_url( $post->ID );
3110
+    ?>
3111 3111
 	<div class="wp_attachment_holder wp-clearfix">
3112 3112
 	<?php
3113 3113
 
3114
-	if ( wp_attachment_is_image( $post->ID ) ) :
3115
-		$image_edit_button = '';
3116
-		if ( wp_image_editor_supports( array( 'mime_type' => $post->post_mime_type ) ) ) {
3117
-			$nonce             = wp_create_nonce( "image_editor-$post->ID" );
3118
-			$image_edit_button = "<input type='button' id='imgedit-open-btn-$post->ID' onclick='imageEdit.open( $post->ID, \"$nonce\" )' class='button' value='" . esc_attr__( 'Edit Image' ) . "' /> <span class='spinner'></span>";
3119
-		}
3114
+    if ( wp_attachment_is_image( $post->ID ) ) :
3115
+        $image_edit_button = '';
3116
+        if ( wp_image_editor_supports( array( 'mime_type' => $post->post_mime_type ) ) ) {
3117
+            $nonce             = wp_create_nonce( "image_editor-$post->ID" );
3118
+            $image_edit_button = "<input type='button' id='imgedit-open-btn-$post->ID' onclick='imageEdit.open( $post->ID, \"$nonce\" )' class='button' value='" . esc_attr__( 'Edit Image' ) . "' /> <span class='spinner'></span>";
3119
+        }
3120 3120
 
3121
-		$open_style     = '';
3122
-		$not_open_style = '';
3121
+        $open_style     = '';
3122
+        $not_open_style = '';
3123 3123
 
3124
-		if ( $open ) {
3125
-			$open_style = ' style="display:none"';
3126
-		} else {
3127
-			$not_open_style = ' style="display:none"';
3128
-		}
3124
+        if ( $open ) {
3125
+            $open_style = ' style="display:none"';
3126
+        } else {
3127
+            $not_open_style = ' style="display:none"';
3128
+        }
3129 3129
 
3130
-		?>
3130
+        ?>
3131 3131
 		<div class="imgedit-response" id="imgedit-response-<?php echo $attachment_id; ?>"></div>
3132 3132
 
3133 3133
 		<div<?php echo $open_style; ?> class="wp_attachment_image wp-clearfix" id="media-head-<?php echo $attachment_id; ?>">
@@ -3137,48 +3137,48 @@  discard block
 block discarded – undo
3137 3137
 		<div<?php echo $not_open_style; ?> class="image-editor" id="image-editor-<?php echo $attachment_id; ?>">
3138 3138
 		<?php
3139 3139
 
3140
-		if ( $open ) {
3141
-			wp_image_editor( $attachment_id );
3142
-		}
3140
+        if ( $open ) {
3141
+            wp_image_editor( $attachment_id );
3142
+        }
3143 3143
 
3144
-		?>
3144
+        ?>
3145 3145
 		</div>
3146 3146
 		<?php
3147
-	elseif ( $attachment_id && wp_attachment_is( 'audio', $post ) ) :
3147
+    elseif ( $attachment_id && wp_attachment_is( 'audio', $post ) ) :
3148 3148
 
3149
-		wp_maybe_generate_attachment_metadata( $post );
3149
+        wp_maybe_generate_attachment_metadata( $post );
3150 3150
 
3151
-		echo wp_audio_shortcode( array( 'src' => $att_url ) );
3151
+        echo wp_audio_shortcode( array( 'src' => $att_url ) );
3152 3152
 
3153
-	elseif ( $attachment_id && wp_attachment_is( 'video', $post ) ) :
3153
+    elseif ( $attachment_id && wp_attachment_is( 'video', $post ) ) :
3154 3154
 
3155
-		wp_maybe_generate_attachment_metadata( $post );
3155
+        wp_maybe_generate_attachment_metadata( $post );
3156 3156
 
3157
-		$meta = wp_get_attachment_metadata( $attachment_id );
3158
-		$w    = ! empty( $meta['width'] ) ? min( $meta['width'], 640 ) : 0;
3159
-		$h    = ! empty( $meta['height'] ) ? $meta['height'] : 0;
3157
+        $meta = wp_get_attachment_metadata( $attachment_id );
3158
+        $w    = ! empty( $meta['width'] ) ? min( $meta['width'], 640 ) : 0;
3159
+        $h    = ! empty( $meta['height'] ) ? $meta['height'] : 0;
3160 3160
 
3161
-		if ( $h && $w < $meta['width'] ) {
3162
-			$h = round( ( $meta['height'] * $w ) / $meta['width'] );
3163
-		}
3161
+        if ( $h && $w < $meta['width'] ) {
3162
+            $h = round( ( $meta['height'] * $w ) / $meta['width'] );
3163
+        }
3164 3164
 
3165
-		$attr = array( 'src' => $att_url );
3165
+        $attr = array( 'src' => $att_url );
3166 3166
 
3167
-		if ( ! empty( $w ) && ! empty( $h ) ) {
3168
-			$attr['width']  = $w;
3169
-			$attr['height'] = $h;
3170
-		}
3167
+        if ( ! empty( $w ) && ! empty( $h ) ) {
3168
+            $attr['width']  = $w;
3169
+            $attr['height'] = $h;
3170
+        }
3171 3171
 
3172
-		$thumb_id = get_post_thumbnail_id( $attachment_id );
3172
+        $thumb_id = get_post_thumbnail_id( $attachment_id );
3173 3173
 
3174
-		if ( ! empty( $thumb_id ) ) {
3175
-			$attr['poster'] = wp_get_attachment_url( $thumb_id );
3176
-		}
3174
+        if ( ! empty( $thumb_id ) ) {
3175
+            $attr['poster'] = wp_get_attachment_url( $thumb_id );
3176
+        }
3177 3177
 
3178
-		echo wp_video_shortcode( $attr );
3178
+        echo wp_video_shortcode( $attr );
3179 3179
 
3180
-	elseif ( isset( $thumb_url[0] ) ) :
3181
-		?>
3180
+    elseif ( isset( $thumb_url[0] ) ) :
3181
+        ?>
3182 3182
 		<div class="wp_attachment_image wp-clearfix" id="media-head-<?php echo $attachment_id; ?>">
3183 3183
 			<p id="thumbnail-head-<?php echo $attachment_id; ?>">
3184 3184
 				<img class="thumbnail" src="<?php echo set_url_scheme( $thumb_url[0] ); ?>" style="max-width:100%" alt="" />
@@ -3186,20 +3186,20 @@  discard block
 block discarded – undo
3186 3186
 		</div>
3187 3187
 		<?php
3188 3188
 
3189
-	else :
3189
+    else :
3190 3190
 
3191
-		/**
3192
-		 * Fires when an attachment type can't be rendered in the edit form.
3193
-		 *
3194
-		 * @since 4.6.0
3195
-		 *
3196
-		 * @param WP_Post $post A post object.
3197
-		 */
3198
-		do_action( 'wp_edit_form_attachment_display', $post );
3191
+        /**
3192
+         * Fires when an attachment type can't be rendered in the edit form.
3193
+         *
3194
+         * @since 4.6.0
3195
+         *
3196
+         * @param WP_Post $post A post object.
3197
+         */
3198
+        do_action( 'wp_edit_form_attachment_display', $post );
3199 3199
 
3200
-	endif;
3200
+    endif;
3201 3201
 
3202
-	?>
3202
+    ?>
3203 3203
 	</div>
3204 3204
 	<div class="wp_attachment_details edit-form-section">
3205 3205
 	<?php if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) : ?>
@@ -3210,19 +3210,19 @@  discard block
 block discarded – undo
3210 3210
 		<p class="attachment-alt-text-description" id="alt-text-description">
3211 3211
 		<?php
3212 3212
 
3213
-		printf(
3214
-			/* translators: 1: Link to tutorial, 2: Additional link attributes, 3: Accessibility text. */
3215
-			__( '<a href="%1$s" %2$s>Learn how to describe the purpose of the image%3$s</a>. Leave empty if the image is purely decorative.' ),
3216
-			esc_url( 'https://www.w3.org/WAI/tutorials/images/decision-tree' ),
3217
-			'target="_blank" rel="noopener"',
3218
-			sprintf(
3219
-				'<span class="screen-reader-text"> %s</span>',
3220
-				/* translators: Accessibility text. */
3221
-				__( '(opens in a new tab)' )
3222
-			)
3223
-		);
3224
-
3225
-		?>
3213
+        printf(
3214
+            /* translators: 1: Link to tutorial, 2: Additional link attributes, 3: Accessibility text. */
3215
+            __( '<a href="%1$s" %2$s>Learn how to describe the purpose of the image%3$s</a>. Leave empty if the image is purely decorative.' ),
3216
+            esc_url( 'https://www.w3.org/WAI/tutorials/images/decision-tree' ),
3217
+            'target="_blank" rel="noopener"',
3218
+            sprintf(
3219
+                '<span class="screen-reader-text"> %s</span>',
3220
+                /* translators: Accessibility text. */
3221
+                __( '(opens in a new tab)' )
3222
+            )
3223
+        );
3224
+
3225
+        ?>
3226 3226
 		</p>
3227 3227
 	<?php endif; ?>
3228 3228
 
@@ -3233,34 +3233,34 @@  discard block
 block discarded – undo
3233 3233
 
3234 3234
 	<?php
3235 3235
 
3236
-	$quicktags_settings = array( 'buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,close' );
3237
-	$editor_args        = array(
3238
-		'textarea_name' => 'content',
3239
-		'textarea_rows' => 5,
3240
-		'media_buttons' => false,
3241
-		'tinymce'       => false,
3242
-		'quicktags'     => $quicktags_settings,
3243
-	);
3236
+    $quicktags_settings = array( 'buttons' => 'strong,em,link,block,del,ins,img,ul,ol,li,code,close' );
3237
+    $editor_args        = array(
3238
+        'textarea_name' => 'content',
3239
+        'textarea_rows' => 5,
3240
+        'media_buttons' => false,
3241
+        'tinymce'       => false,
3242
+        'quicktags'     => $quicktags_settings,
3243
+    );
3244 3244
 
3245
-	?>
3245
+    ?>
3246 3246
 
3247 3247
 	<label for="attachment_content" class="attachment-content-description"><strong><?php _e( 'Description' ); ?></strong>
3248 3248
 	<?php
3249 3249
 
3250
-	if ( preg_match( '#^(audio|video)/#', $post->post_mime_type ) ) {
3251
-		echo ': ' . __( 'Displayed on attachment pages.' );
3252
-	}
3250
+    if ( preg_match( '#^(audio|video)/#', $post->post_mime_type ) ) {
3251
+        echo ': ' . __( 'Displayed on attachment pages.' );
3252
+    }
3253 3253
 
3254
-	?>
3254
+    ?>
3255 3255
 	</label>
3256 3256
 	<?php wp_editor( format_to_edit( $post->post_content ), 'attachment_content', $editor_args ); ?>
3257 3257
 
3258 3258
 	</div>
3259 3259
 	<?php
3260 3260
 
3261
-	$extras = get_compat_media_markup( $post->ID );
3262
-	echo $extras['item'];
3263
-	echo '<input type="hidden" id="image-edit-context" value="edit-attachment" />' . "\n";
3261
+    $extras = get_compat_media_markup( $post->ID );
3262
+    echo $extras['item'];
3263
+    echo '<input type="hidden" id="image-edit-context" value="edit-attachment" />' . "\n";
3264 3264
 }
3265 3265
 
3266 3266
 /**
@@ -3269,33 +3269,33 @@  discard block
 block discarded – undo
3269 3269
  * @since 3.5.0
3270 3270
  */
3271 3271
 function attachment_submitbox_metadata() {
3272
-	$post          = get_post();
3273
-	$attachment_id = $post->ID;
3272
+    $post          = get_post();
3273
+    $attachment_id = $post->ID;
3274 3274
 
3275
-	$file     = get_attached_file( $attachment_id );
3276
-	$filename = esc_html( wp_basename( $file ) );
3275
+    $file     = get_attached_file( $attachment_id );
3276
+    $filename = esc_html( wp_basename( $file ) );
3277 3277
 
3278
-	$media_dims = '';
3279
-	$meta       = wp_get_attachment_metadata( $attachment_id );
3278
+    $media_dims = '';
3279
+    $meta       = wp_get_attachment_metadata( $attachment_id );
3280 3280
 
3281
-	if ( isset( $meta['width'], $meta['height'] ) ) {
3282
-		$media_dims .= "<span id='media-dims-$attachment_id'>{$meta['width']}&nbsp;&times;&nbsp;{$meta['height']}</span> ";
3283
-	}
3284
-	/** This filter is documented in wp-admin/includes/media.php */
3285
-	$media_dims = apply_filters( 'media_meta', $media_dims, $post );
3281
+    if ( isset( $meta['width'], $meta['height'] ) ) {
3282
+        $media_dims .= "<span id='media-dims-$attachment_id'>{$meta['width']}&nbsp;&times;&nbsp;{$meta['height']}</span> ";
3283
+    }
3284
+    /** This filter is documented in wp-admin/includes/media.php */
3285
+    $media_dims = apply_filters( 'media_meta', $media_dims, $post );
3286 3286
 
3287
-	$att_url = wp_get_attachment_url( $attachment_id );
3287
+    $att_url = wp_get_attachment_url( $attachment_id );
3288 3288
 
3289
-	$author = new WP_User( $post->post_author );
3289
+    $author = new WP_User( $post->post_author );
3290 3290
 
3291
-	$uploaded_by_name = __( '(no author)' );
3292
-	$uploaded_by_link = '';
3291
+    $uploaded_by_name = __( '(no author)' );
3292
+    $uploaded_by_link = '';
3293 3293
 
3294
-	if ( $author->exists() ) {
3295
-		$uploaded_by_name = $author->display_name ? $author->display_name : $author->nickname;
3296
-		$uploaded_by_link = get_edit_user_link( $author->ID );
3297
-	}
3298
-	?>
3294
+    if ( $author->exists() ) {
3295
+        $uploaded_by_name = $author->display_name ? $author->display_name : $author->nickname;
3296
+        $uploaded_by_link = get_edit_user_link( $author->ID );
3297
+    }
3298
+    ?>
3299 3299
 	<div class="misc-pub-section misc-pub-uploadedby">
3300 3300
 		<?php if ( $uploaded_by_link ) { ?>
3301 3301
 			<?php _e( 'Uploaded by:' ); ?> <a href="<?php echo $uploaded_by_link; ?>"><strong><?php echo $uploaded_by_name; ?></strong></a>
@@ -3305,12 +3305,12 @@  discard block
 block discarded – undo
3305 3305
 	</div>
3306 3306
 
3307 3307
 	<?php
3308
-	if ( $post->post_parent ) {
3309
-		$post_parent = get_post( $post->post_parent );
3310
-		if ( $post_parent ) {
3311
-			$uploaded_to_title = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' );
3312
-			$uploaded_to_link  = get_edit_post_link( $post->post_parent, 'raw' );
3313
-			?>
3308
+    if ( $post->post_parent ) {
3309
+        $post_parent = get_post( $post->post_parent );
3310
+        if ( $post_parent ) {
3311
+            $uploaded_to_title = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' );
3312
+            $uploaded_to_link  = get_edit_post_link( $post->post_parent, 'raw' );
3313
+            ?>
3314 3314
 			<div class="misc-pub-section misc-pub-uploadedto">
3315 3315
 				<?php if ( $uploaded_to_link ) { ?>
3316 3316
 					<?php _e( 'Uploaded to:' ); ?> <a href="<?php echo $uploaded_to_link; ?>"><strong><?php echo $uploaded_to_title; ?></strong></a>
@@ -3319,9 +3319,9 @@  discard block
 block discarded – undo
3319 3319
 				<?php } ?>
3320 3320
 			</div>
3321 3321
 			<?php
3322
-		}
3323
-	}
3324
-	?>
3322
+        }
3323
+    }
3324
+    ?>
3325 3325
 
3326 3326
 	<div class="misc-pub-section misc-pub-attachment">
3327 3327
 		<label for="attachment_url"><?php _e( 'File URL:' ); ?></label>
@@ -3339,131 +3339,131 @@  discard block
 block discarded – undo
3339 3339
 		<strong>
3340 3340
 		<?php
3341 3341
 
3342
-		if ( preg_match( '/^.*?\.(\w+)$/', get_attached_file( $post->ID ), $matches ) ) {
3343
-			echo esc_html( strtoupper( $matches[1] ) );
3344
-			list( $mime_type ) = explode( '/', $post->post_mime_type );
3345
-			if ( 'image' !== $mime_type && ! empty( $meta['mime_type'] ) ) {
3346
-				if ( "$mime_type/" . strtolower( $matches[1] ) !== $meta['mime_type'] ) {
3347
-					echo ' (' . $meta['mime_type'] . ')';
3348
-				}
3349
-			}
3350
-		} else {
3351
-			echo strtoupper( str_replace( 'image/', '', $post->post_mime_type ) );
3352
-		}
3353
-
3354
-		?>
3342
+        if ( preg_match( '/^.*?\.(\w+)$/', get_attached_file( $post->ID ), $matches ) ) {
3343
+            echo esc_html( strtoupper( $matches[1] ) );
3344
+            list( $mime_type ) = explode( '/', $post->post_mime_type );
3345
+            if ( 'image' !== $mime_type && ! empty( $meta['mime_type'] ) ) {
3346
+                if ( "$mime_type/" . strtolower( $matches[1] ) !== $meta['mime_type'] ) {
3347
+                    echo ' (' . $meta['mime_type'] . ')';
3348
+                }
3349
+            }
3350
+        } else {
3351
+            echo strtoupper( str_replace( 'image/', '', $post->post_mime_type ) );
3352
+        }
3353
+
3354
+        ?>
3355 3355
 		</strong>
3356 3356
 	</div>
3357 3357
 
3358 3358
 	<?php
3359 3359
 
3360
-	$file_size = false;
3360
+    $file_size = false;
3361 3361
 
3362
-	if ( isset( $meta['filesize'] ) ) {
3363
-		$file_size = $meta['filesize'];
3364
-	} elseif ( file_exists( $file ) ) {
3365
-		$file_size = wp_filesize( $file );
3366
-	}
3362
+    if ( isset( $meta['filesize'] ) ) {
3363
+        $file_size = $meta['filesize'];
3364
+    } elseif ( file_exists( $file ) ) {
3365
+        $file_size = wp_filesize( $file );
3366
+    }
3367 3367
 
3368
-	if ( ! empty( $file_size ) ) {
3369
-		?>
3368
+    if ( ! empty( $file_size ) ) {
3369
+        ?>
3370 3370
 		<div class="misc-pub-section misc-pub-filesize">
3371 3371
 			<?php _e( 'File size:' ); ?> <strong><?php echo size_format( $file_size ); ?></strong>
3372 3372
 		</div>
3373 3373
 		<?php
3374
-	}
3375
-
3376
-	if ( preg_match( '#^(audio|video)/#', $post->post_mime_type ) ) {
3377
-		$fields = array(
3378
-			'length_formatted' => __( 'Length:' ),
3379
-			'bitrate'          => __( 'Bitrate:' ),
3380
-		);
3381
-
3382
-		/**
3383
-		 * Filters the audio and video metadata fields to be shown in the publish meta box.
3384
-		 *
3385
-		 * The key for each item in the array should correspond to an attachment
3386
-		 * metadata key, and the value should be the desired label.
3387
-		 *
3388
-		 * @since 3.7.0
3389
-		 * @since 4.9.0 Added the `$post` parameter.
3390
-		 *
3391
-		 * @param array   $fields An array of the attachment metadata keys and labels.
3392
-		 * @param WP_Post $post   WP_Post object for the current attachment.
3393
-		 */
3394
-		$fields = apply_filters( 'media_submitbox_misc_sections', $fields, $post );
3395
-
3396
-		foreach ( $fields as $key => $label ) {
3397
-			if ( empty( $meta[ $key ] ) ) {
3398
-				continue;
3399
-			}
3400
-
3401
-			?>
3374
+    }
3375
+
3376
+    if ( preg_match( '#^(audio|video)/#', $post->post_mime_type ) ) {
3377
+        $fields = array(
3378
+            'length_formatted' => __( 'Length:' ),
3379
+            'bitrate'          => __( 'Bitrate:' ),
3380
+        );
3381
+
3382
+        /**
3383
+         * Filters the audio and video metadata fields to be shown in the publish meta box.
3384
+         *
3385
+         * The key for each item in the array should correspond to an attachment
3386
+         * metadata key, and the value should be the desired label.
3387
+         *
3388
+         * @since 3.7.0
3389
+         * @since 4.9.0 Added the `$post` parameter.
3390
+         *
3391
+         * @param array   $fields An array of the attachment metadata keys and labels.
3392
+         * @param WP_Post $post   WP_Post object for the current attachment.
3393
+         */
3394
+        $fields = apply_filters( 'media_submitbox_misc_sections', $fields, $post );
3395
+
3396
+        foreach ( $fields as $key => $label ) {
3397
+            if ( empty( $meta[ $key ] ) ) {
3398
+                continue;
3399
+            }
3400
+
3401
+            ?>
3402 3402
 			<div class="misc-pub-section misc-pub-mime-meta misc-pub-<?php echo sanitize_html_class( $key ); ?>">
3403 3403
 				<?php echo $label; ?>
3404 3404
 				<strong>
3405 3405
 				<?php
3406 3406
 
3407
-				switch ( $key ) {
3408
-					case 'bitrate':
3409
-						echo round( $meta['bitrate'] / 1000 ) . 'kb/s';
3410
-						if ( ! empty( $meta['bitrate_mode'] ) ) {
3411
-							echo ' ' . strtoupper( esc_html( $meta['bitrate_mode'] ) );
3412
-						}
3413
-						break;
3414
-					default:
3415
-						echo esc_html( $meta[ $key ] );
3416
-						break;
3417
-				}
3418
-
3419
-				?>
3407
+                switch ( $key ) {
3408
+                    case 'bitrate':
3409
+                        echo round( $meta['bitrate'] / 1000 ) . 'kb/s';
3410
+                        if ( ! empty( $meta['bitrate_mode'] ) ) {
3411
+                            echo ' ' . strtoupper( esc_html( $meta['bitrate_mode'] ) );
3412
+                        }
3413
+                        break;
3414
+                    default:
3415
+                        echo esc_html( $meta[ $key ] );
3416
+                        break;
3417
+                }
3418
+
3419
+                ?>
3420 3420
 				</strong>
3421 3421
 			</div>
3422 3422
 			<?php
3423
-		}
3424
-
3425
-		$fields = array(
3426
-			'dataformat' => __( 'Audio Format:' ),
3427
-			'codec'      => __( 'Audio Codec:' ),
3428
-		);
3429
-
3430
-		/**
3431
-		 * Filters the audio attachment metadata fields to be shown in the publish meta box.
3432
-		 *
3433
-		 * The key for each item in the array should correspond to an attachment
3434
-		 * metadata key, and the value should be the desired label.
3435
-		 *
3436
-		 * @since 3.7.0
3437
-		 * @since 4.9.0 Added the `$post` parameter.
3438
-		 *
3439
-		 * @param array   $fields An array of the attachment metadata keys and labels.
3440
-		 * @param WP_Post $post   WP_Post object for the current attachment.
3441
-		 */
3442
-		$audio_fields = apply_filters( 'audio_submitbox_misc_sections', $fields, $post );
3443
-
3444
-		foreach ( $audio_fields as $key => $label ) {
3445
-			if ( empty( $meta['audio'][ $key ] ) ) {
3446
-				continue;
3447
-			}
3448
-
3449
-			?>
3423
+        }
3424
+
3425
+        $fields = array(
3426
+            'dataformat' => __( 'Audio Format:' ),
3427
+            'codec'      => __( 'Audio Codec:' ),
3428
+        );
3429
+
3430
+        /**
3431
+         * Filters the audio attachment metadata fields to be shown in the publish meta box.
3432
+         *
3433
+         * The key for each item in the array should correspond to an attachment
3434
+         * metadata key, and the value should be the desired label.
3435
+         *
3436
+         * @since 3.7.0
3437
+         * @since 4.9.0 Added the `$post` parameter.
3438
+         *
3439
+         * @param array   $fields An array of the attachment metadata keys and labels.
3440
+         * @param WP_Post $post   WP_Post object for the current attachment.
3441
+         */
3442
+        $audio_fields = apply_filters( 'audio_submitbox_misc_sections', $fields, $post );
3443
+
3444
+        foreach ( $audio_fields as $key => $label ) {
3445
+            if ( empty( $meta['audio'][ $key ] ) ) {
3446
+                continue;
3447
+            }
3448
+
3449
+            ?>
3450 3450
 			<div class="misc-pub-section misc-pub-audio misc-pub-<?php echo sanitize_html_class( $key ); ?>">
3451 3451
 				<?php echo $label; ?> <strong><?php echo esc_html( $meta['audio'][ $key ] ); ?></strong>
3452 3452
 			</div>
3453 3453
 			<?php
3454
-		}
3455
-	}
3454
+        }
3455
+    }
3456 3456
 
3457
-	if ( $media_dims ) {
3458
-		?>
3457
+    if ( $media_dims ) {
3458
+        ?>
3459 3459
 		<div class="misc-pub-section misc-pub-dimensions">
3460 3460
 			<?php _e( 'Dimensions:' ); ?> <strong><?php echo $media_dims; ?></strong>
3461 3461
 		</div>
3462 3462
 		<?php
3463
-	}
3463
+    }
3464 3464
 
3465
-	if ( ! empty( $meta['original_image'] ) ) {
3466
-		?>
3465
+    if ( ! empty( $meta['original_image'] ) ) {
3466
+        ?>
3467 3467
 		<div class="misc-pub-section misc-pub-original-image">
3468 3468
 			<?php _e( 'Original image:' ); ?>
3469 3469
 			<a href="<?php echo esc_url( wp_get_original_image_url( $attachment_id ) ); ?>">
@@ -3471,7 +3471,7 @@  discard block
 block discarded – undo
3471 3471
 			</a>
3472 3472
 		</div>
3473 3473
 		<?php
3474
-	}
3474
+    }
3475 3475
 }
3476 3476
 
3477 3477
 /**
@@ -3483,40 +3483,40 @@  discard block
 block discarded – undo
3483 3483
  * @param array $data Data supplied by ID3 tags.
3484 3484
  */
3485 3485
 function wp_add_id3_tag_data( &$metadata, $data ) {
3486
-	foreach ( array( 'id3v2', 'id3v1' ) as $version ) {
3487
-		if ( ! empty( $data[ $version ]['comments'] ) ) {
3488
-			foreach ( $data[ $version ]['comments'] as $key => $list ) {
3489
-				if ( 'length' !== $key && ! empty( $list ) ) {
3490
-					$metadata[ $key ] = wp_kses_post( reset( $list ) );
3491
-					// Fix bug in byte stream analysis.
3492
-					if ( 'terms_of_use' === $key && 0 === strpos( $metadata[ $key ], 'yright notice.' ) ) {
3493
-						$metadata[ $key ] = 'Cop' . $metadata[ $key ];
3494
-					}
3495
-				}
3496
-			}
3497
-			break;
3498
-		}
3499
-	}
3500
-
3501
-	if ( ! empty( $data['id3v2']['APIC'] ) ) {
3502
-		$image = reset( $data['id3v2']['APIC'] );
3503
-		if ( ! empty( $image['data'] ) ) {
3504
-			$metadata['image'] = array(
3505
-				'data'   => $image['data'],
3506
-				'mime'   => $image['image_mime'],
3507
-				'width'  => $image['image_width'],
3508
-				'height' => $image['image_height'],
3509
-			);
3510
-		}
3511
-	} elseif ( ! empty( $data['comments']['picture'] ) ) {
3512
-		$image = reset( $data['comments']['picture'] );
3513
-		if ( ! empty( $image['data'] ) ) {
3514
-			$metadata['image'] = array(
3515
-				'data' => $image['data'],
3516
-				'mime' => $image['image_mime'],
3517
-			);
3518
-		}
3519
-	}
3486
+    foreach ( array( 'id3v2', 'id3v1' ) as $version ) {
3487
+        if ( ! empty( $data[ $version ]['comments'] ) ) {
3488
+            foreach ( $data[ $version ]['comments'] as $key => $list ) {
3489
+                if ( 'length' !== $key && ! empty( $list ) ) {
3490
+                    $metadata[ $key ] = wp_kses_post( reset( $list ) );
3491
+                    // Fix bug in byte stream analysis.
3492
+                    if ( 'terms_of_use' === $key && 0 === strpos( $metadata[ $key ], 'yright notice.' ) ) {
3493
+                        $metadata[ $key ] = 'Cop' . $metadata[ $key ];
3494
+                    }
3495
+                }
3496
+            }
3497
+            break;
3498
+        }
3499
+    }
3500
+
3501
+    if ( ! empty( $data['id3v2']['APIC'] ) ) {
3502
+        $image = reset( $data['id3v2']['APIC'] );
3503
+        if ( ! empty( $image['data'] ) ) {
3504
+            $metadata['image'] = array(
3505
+                'data'   => $image['data'],
3506
+                'mime'   => $image['image_mime'],
3507
+                'width'  => $image['image_width'],
3508
+                'height' => $image['image_height'],
3509
+            );
3510
+        }
3511
+    } elseif ( ! empty( $data['comments']['picture'] ) ) {
3512
+        $image = reset( $data['comments']['picture'] );
3513
+        if ( ! empty( $image['data'] ) ) {
3514
+            $metadata['image'] = array(
3515
+                'data' => $image['data'],
3516
+                'mime' => $image['image_mime'],
3517
+            );
3518
+        }
3519
+    }
3520 3520
 }
3521 3521
 
3522 3522
 /**
@@ -3528,109 +3528,109 @@  discard block
 block discarded – undo
3528 3528
  * @return array|false Returns array of metadata, if found.
3529 3529
  */
3530 3530
 function wp_read_video_metadata( $file ) {
3531
-	if ( ! file_exists( $file ) ) {
3532
-		return false;
3533
-	}
3534
-
3535
-	$metadata = array();
3536
-
3537
-	if ( ! defined( 'GETID3_TEMP_DIR' ) ) {
3538
-		define( 'GETID3_TEMP_DIR', get_temp_dir() );
3539
-	}
3540
-
3541
-	if ( ! class_exists( 'getID3', false ) ) {
3542
-		require ABSPATH . WPINC . '/ID3/getid3.php';
3543
-	}
3544
-
3545
-	$id3 = new getID3();
3546
-	// Required to get the `created_timestamp` value.
3547
-	$id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
3548
-
3549
-	$data = $id3->analyze( $file );
3550
-
3551
-	if ( isset( $data['video']['lossless'] ) ) {
3552
-		$metadata['lossless'] = $data['video']['lossless'];
3553
-	}
3554
-
3555
-	if ( ! empty( $data['video']['bitrate'] ) ) {
3556
-		$metadata['bitrate'] = (int) $data['video']['bitrate'];
3557
-	}
3558
-
3559
-	if ( ! empty( $data['video']['bitrate_mode'] ) ) {
3560
-		$metadata['bitrate_mode'] = $data['video']['bitrate_mode'];
3561
-	}
3562
-
3563
-	if ( ! empty( $data['filesize'] ) ) {
3564
-		$metadata['filesize'] = (int) $data['filesize'];
3565
-	}
3566
-
3567
-	if ( ! empty( $data['mime_type'] ) ) {
3568
-		$metadata['mime_type'] = $data['mime_type'];
3569
-	}
3570
-
3571
-	if ( ! empty( $data['playtime_seconds'] ) ) {
3572
-		$metadata['length'] = (int) round( $data['playtime_seconds'] );
3573
-	}
3574
-
3575
-	if ( ! empty( $data['playtime_string'] ) ) {
3576
-		$metadata['length_formatted'] = $data['playtime_string'];
3577
-	}
3578
-
3579
-	if ( ! empty( $data['video']['resolution_x'] ) ) {
3580
-		$metadata['width'] = (int) $data['video']['resolution_x'];
3581
-	}
3582
-
3583
-	if ( ! empty( $data['video']['resolution_y'] ) ) {
3584
-		$metadata['height'] = (int) $data['video']['resolution_y'];
3585
-	}
3586
-
3587
-	if ( ! empty( $data['fileformat'] ) ) {
3588
-		$metadata['fileformat'] = $data['fileformat'];
3589
-	}
3590
-
3591
-	if ( ! empty( $data['video']['dataformat'] ) ) {
3592
-		$metadata['dataformat'] = $data['video']['dataformat'];
3593
-	}
3594
-
3595
-	if ( ! empty( $data['video']['encoder'] ) ) {
3596
-		$metadata['encoder'] = $data['video']['encoder'];
3597
-	}
3598
-
3599
-	if ( ! empty( $data['video']['codec'] ) ) {
3600
-		$metadata['codec'] = $data['video']['codec'];
3601
-	}
3602
-
3603
-	if ( ! empty( $data['audio'] ) ) {
3604
-		unset( $data['audio']['streams'] );
3605
-		$metadata['audio'] = $data['audio'];
3606
-	}
3607
-
3608
-	if ( empty( $metadata['created_timestamp'] ) ) {
3609
-		$created_timestamp = wp_get_media_creation_timestamp( $data );
3610
-
3611
-		if ( false !== $created_timestamp ) {
3612
-			$metadata['created_timestamp'] = $created_timestamp;
3613
-		}
3614
-	}
3615
-
3616
-	wp_add_id3_tag_data( $metadata, $data );
3617
-
3618
-	$file_format = isset( $metadata['fileformat'] ) ? $metadata['fileformat'] : null;
3619
-
3620
-	/**
3621
-	 * Filters the array of metadata retrieved from a video.
3622
-	 *
3623
-	 * In core, usually this selection is what is stored.
3624
-	 * More complete data can be parsed from the `$data` parameter.
3625
-	 *
3626
-	 * @since 4.9.0
3627
-	 *
3628
-	 * @param array  $metadata       Filtered Video metadata.
3629
-	 * @param string $file           Path to video file.
3630
-	 * @param string $file_format    File format of video, as analyzed by getID3.
3631
-	 * @param array  $data           Raw metadata from getID3.
3632
-	 */
3633
-	return apply_filters( 'wp_read_video_metadata', $metadata, $file, $file_format, $data );
3531
+    if ( ! file_exists( $file ) ) {
3532
+        return false;
3533
+    }
3534
+
3535
+    $metadata = array();
3536
+
3537
+    if ( ! defined( 'GETID3_TEMP_DIR' ) ) {
3538
+        define( 'GETID3_TEMP_DIR', get_temp_dir() );
3539
+    }
3540
+
3541
+    if ( ! class_exists( 'getID3', false ) ) {
3542
+        require ABSPATH . WPINC . '/ID3/getid3.php';
3543
+    }
3544
+
3545
+    $id3 = new getID3();
3546
+    // Required to get the `created_timestamp` value.
3547
+    $id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
3548
+
3549
+    $data = $id3->analyze( $file );
3550
+
3551
+    if ( isset( $data['video']['lossless'] ) ) {
3552
+        $metadata['lossless'] = $data['video']['lossless'];
3553
+    }
3554
+
3555
+    if ( ! empty( $data['video']['bitrate'] ) ) {
3556
+        $metadata['bitrate'] = (int) $data['video']['bitrate'];
3557
+    }
3558
+
3559
+    if ( ! empty( $data['video']['bitrate_mode'] ) ) {
3560
+        $metadata['bitrate_mode'] = $data['video']['bitrate_mode'];
3561
+    }
3562
+
3563
+    if ( ! empty( $data['filesize'] ) ) {
3564
+        $metadata['filesize'] = (int) $data['filesize'];
3565
+    }
3566
+
3567
+    if ( ! empty( $data['mime_type'] ) ) {
3568
+        $metadata['mime_type'] = $data['mime_type'];
3569
+    }
3570
+
3571
+    if ( ! empty( $data['playtime_seconds'] ) ) {
3572
+        $metadata['length'] = (int) round( $data['playtime_seconds'] );
3573
+    }
3574
+
3575
+    if ( ! empty( $data['playtime_string'] ) ) {
3576
+        $metadata['length_formatted'] = $data['playtime_string'];
3577
+    }
3578
+
3579
+    if ( ! empty( $data['video']['resolution_x'] ) ) {
3580
+        $metadata['width'] = (int) $data['video']['resolution_x'];
3581
+    }
3582
+
3583
+    if ( ! empty( $data['video']['resolution_y'] ) ) {
3584
+        $metadata['height'] = (int) $data['video']['resolution_y'];
3585
+    }
3586
+
3587
+    if ( ! empty( $data['fileformat'] ) ) {
3588
+        $metadata['fileformat'] = $data['fileformat'];
3589
+    }
3590
+
3591
+    if ( ! empty( $data['video']['dataformat'] ) ) {
3592
+        $metadata['dataformat'] = $data['video']['dataformat'];
3593
+    }
3594
+
3595
+    if ( ! empty( $data['video']['encoder'] ) ) {
3596
+        $metadata['encoder'] = $data['video']['encoder'];
3597
+    }
3598
+
3599
+    if ( ! empty( $data['video']['codec'] ) ) {
3600
+        $metadata['codec'] = $data['video']['codec'];
3601
+    }
3602
+
3603
+    if ( ! empty( $data['audio'] ) ) {
3604
+        unset( $data['audio']['streams'] );
3605
+        $metadata['audio'] = $data['audio'];
3606
+    }
3607
+
3608
+    if ( empty( $metadata['created_timestamp'] ) ) {
3609
+        $created_timestamp = wp_get_media_creation_timestamp( $data );
3610
+
3611
+        if ( false !== $created_timestamp ) {
3612
+            $metadata['created_timestamp'] = $created_timestamp;
3613
+        }
3614
+    }
3615
+
3616
+    wp_add_id3_tag_data( $metadata, $data );
3617
+
3618
+    $file_format = isset( $metadata['fileformat'] ) ? $metadata['fileformat'] : null;
3619
+
3620
+    /**
3621
+     * Filters the array of metadata retrieved from a video.
3622
+     *
3623
+     * In core, usually this selection is what is stored.
3624
+     * More complete data can be parsed from the `$data` parameter.
3625
+     *
3626
+     * @since 4.9.0
3627
+     *
3628
+     * @param array  $metadata       Filtered Video metadata.
3629
+     * @param string $file           Path to video file.
3630
+     * @param string $file_format    File format of video, as analyzed by getID3.
3631
+     * @param array  $data           Raw metadata from getID3.
3632
+     */
3633
+    return apply_filters( 'wp_read_video_metadata', $metadata, $file, $file_format, $data );
3634 3634
 }
3635 3635
 
3636 3636
 /**
@@ -3642,62 +3642,62 @@  discard block
 block discarded – undo
3642 3642
  * @return array|false Returns array of metadata, if found.
3643 3643
  */
3644 3644
 function wp_read_audio_metadata( $file ) {
3645
-	if ( ! file_exists( $file ) ) {
3646
-		return false;
3647
-	}
3645
+    if ( ! file_exists( $file ) ) {
3646
+        return false;
3647
+    }
3648 3648
 
3649
-	$metadata = array();
3649
+    $metadata = array();
3650 3650
 
3651
-	if ( ! defined( 'GETID3_TEMP_DIR' ) ) {
3652
-		define( 'GETID3_TEMP_DIR', get_temp_dir() );
3653
-	}
3651
+    if ( ! defined( 'GETID3_TEMP_DIR' ) ) {
3652
+        define( 'GETID3_TEMP_DIR', get_temp_dir() );
3653
+    }
3654 3654
 
3655
-	if ( ! class_exists( 'getID3', false ) ) {
3656
-		require ABSPATH . WPINC . '/ID3/getid3.php';
3657
-	}
3655
+    if ( ! class_exists( 'getID3', false ) ) {
3656
+        require ABSPATH . WPINC . '/ID3/getid3.php';
3657
+    }
3658 3658
 
3659
-	$id3 = new getID3();
3660
-	// Required to get the `created_timestamp` value.
3661
-	$id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
3659
+    $id3 = new getID3();
3660
+    // Required to get the `created_timestamp` value.
3661
+    $id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
3662 3662
 
3663
-	$data = $id3->analyze( $file );
3663
+    $data = $id3->analyze( $file );
3664 3664
 
3665
-	if ( ! empty( $data['audio'] ) ) {
3666
-		unset( $data['audio']['streams'] );
3667
-		$metadata = $data['audio'];
3668
-	}
3665
+    if ( ! empty( $data['audio'] ) ) {
3666
+        unset( $data['audio']['streams'] );
3667
+        $metadata = $data['audio'];
3668
+    }
3669 3669
 
3670
-	if ( ! empty( $data['fileformat'] ) ) {
3671
-		$metadata['fileformat'] = $data['fileformat'];
3672
-	}
3670
+    if ( ! empty( $data['fileformat'] ) ) {
3671
+        $metadata['fileformat'] = $data['fileformat'];
3672
+    }
3673 3673
 
3674
-	if ( ! empty( $data['filesize'] ) ) {
3675
-		$metadata['filesize'] = (int) $data['filesize'];
3676
-	}
3674
+    if ( ! empty( $data['filesize'] ) ) {
3675
+        $metadata['filesize'] = (int) $data['filesize'];
3676
+    }
3677 3677
 
3678
-	if ( ! empty( $data['mime_type'] ) ) {
3679
-		$metadata['mime_type'] = $data['mime_type'];
3680
-	}
3678
+    if ( ! empty( $data['mime_type'] ) ) {
3679
+        $metadata['mime_type'] = $data['mime_type'];
3680
+    }
3681 3681
 
3682
-	if ( ! empty( $data['playtime_seconds'] ) ) {
3683
-		$metadata['length'] = (int) round( $data['playtime_seconds'] );
3684
-	}
3682
+    if ( ! empty( $data['playtime_seconds'] ) ) {
3683
+        $metadata['length'] = (int) round( $data['playtime_seconds'] );
3684
+    }
3685 3685
 
3686
-	if ( ! empty( $data['playtime_string'] ) ) {
3687
-		$metadata['length_formatted'] = $data['playtime_string'];
3688
-	}
3686
+    if ( ! empty( $data['playtime_string'] ) ) {
3687
+        $metadata['length_formatted'] = $data['playtime_string'];
3688
+    }
3689 3689
 
3690
-	if ( empty( $metadata['created_timestamp'] ) ) {
3691
-		$created_timestamp = wp_get_media_creation_timestamp( $data );
3690
+    if ( empty( $metadata['created_timestamp'] ) ) {
3691
+        $created_timestamp = wp_get_media_creation_timestamp( $data );
3692 3692
 
3693
-		if ( false !== $created_timestamp ) {
3694
-			$metadata['created_timestamp'] = $created_timestamp;
3695
-		}
3696
-	}
3693
+        if ( false !== $created_timestamp ) {
3694
+            $metadata['created_timestamp'] = $created_timestamp;
3695
+        }
3696
+    }
3697 3697
 
3698
-	wp_add_id3_tag_data( $metadata, $data );
3698
+    wp_add_id3_tag_data( $metadata, $data );
3699 3699
 
3700
-	return $metadata;
3700
+    return $metadata;
3701 3701
 }
3702 3702
 
3703 3703
 /**
@@ -3715,37 +3715,37 @@  discard block
 block discarded – undo
3715 3715
  *                   or a boolean FALSE if a timestamp could not be determined.
3716 3716
  */
3717 3717
 function wp_get_media_creation_timestamp( $metadata ) {
3718
-	$creation_date = false;
3719
-
3720
-	if ( empty( $metadata['fileformat'] ) ) {
3721
-		return $creation_date;
3722
-	}
3723
-
3724
-	switch ( $metadata['fileformat'] ) {
3725
-		case 'asf':
3726
-			if ( isset( $metadata['asf']['file_properties_object']['creation_date_unix'] ) ) {
3727
-				$creation_date = (int) $metadata['asf']['file_properties_object']['creation_date_unix'];
3728
-			}
3729
-			break;
3730
-
3731
-		case 'matroska':
3732
-		case 'webm':
3733
-			if ( isset( $metadata['matroska']['comments']['creation_time'][0] ) ) {
3734
-				$creation_date = strtotime( $metadata['matroska']['comments']['creation_time'][0] );
3735
-			} elseif ( isset( $metadata['matroska']['info'][0]['DateUTC_unix'] ) ) {
3736
-				$creation_date = (int) $metadata['matroska']['info'][0]['DateUTC_unix'];
3737
-			}
3738
-			break;
3739
-
3740
-		case 'quicktime':
3741
-		case 'mp4':
3742
-			if ( isset( $metadata['quicktime']['moov']['subatoms'][0]['creation_time_unix'] ) ) {
3743
-				$creation_date = (int) $metadata['quicktime']['moov']['subatoms'][0]['creation_time_unix'];
3744
-			}
3745
-			break;
3746
-	}
3747
-
3748
-	return $creation_date;
3718
+    $creation_date = false;
3719
+
3720
+    if ( empty( $metadata['fileformat'] ) ) {
3721
+        return $creation_date;
3722
+    }
3723
+
3724
+    switch ( $metadata['fileformat'] ) {
3725
+        case 'asf':
3726
+            if ( isset( $metadata['asf']['file_properties_object']['creation_date_unix'] ) ) {
3727
+                $creation_date = (int) $metadata['asf']['file_properties_object']['creation_date_unix'];
3728
+            }
3729
+            break;
3730
+
3731
+        case 'matroska':
3732
+        case 'webm':
3733
+            if ( isset( $metadata['matroska']['comments']['creation_time'][0] ) ) {
3734
+                $creation_date = strtotime( $metadata['matroska']['comments']['creation_time'][0] );
3735
+            } elseif ( isset( $metadata['matroska']['info'][0]['DateUTC_unix'] ) ) {
3736
+                $creation_date = (int) $metadata['matroska']['info'][0]['DateUTC_unix'];
3737
+            }
3738
+            break;
3739
+
3740
+        case 'quicktime':
3741
+        case 'mp4':
3742
+            if ( isset( $metadata['quicktime']['moov']['subatoms'][0]['creation_time_unix'] ) ) {
3743
+                $creation_date = (int) $metadata['quicktime']['moov']['subatoms'][0]['creation_time_unix'];
3744
+            }
3745
+            break;
3746
+    }
3747
+
3748
+    return $creation_date;
3749 3749
 }
3750 3750
 
3751 3751
 /**
@@ -3760,67 +3760,67 @@  discard block
 block discarded – undo
3760 3760
  *                          Default 'attach'.
3761 3761
  */
3762 3762
 function wp_media_attach_action( $parent_id, $action = 'attach' ) {
3763
-	global $wpdb;
3764
-
3765
-	if ( ! $parent_id ) {
3766
-		return;
3767
-	}
3768
-
3769
-	if ( ! current_user_can( 'edit_post', $parent_id ) ) {
3770
-		wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
3771
-	}
3772
-
3773
-	$ids = array();
3774
-
3775
-	foreach ( (array) $_REQUEST['media'] as $attachment_id ) {
3776
-		$attachment_id = (int) $attachment_id;
3777
-
3778
-		if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
3779
-			continue;
3780
-		}
3781
-
3782
-		$ids[] = $attachment_id;
3783
-	}
3784
-
3785
-	if ( ! empty( $ids ) ) {
3786
-		$ids_string = implode( ',', $ids );
3787
-
3788
-		if ( 'attach' === $action ) {
3789
-			$result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $ids_string )", $parent_id ) );
3790
-		} else {
3791
-			$result = $wpdb->query( "UPDATE $wpdb->posts SET post_parent = 0 WHERE post_type = 'attachment' AND ID IN ( $ids_string )" );
3792
-		}
3793
-	}
3794
-
3795
-	if ( isset( $result ) ) {
3796
-		foreach ( $ids as $attachment_id ) {
3797
-			/**
3798
-			 * Fires when media is attached or detached from a post.
3799
-			 *
3800
-			 * @since 5.5.0
3801
-			 *
3802
-			 * @param string $action        Attach/detach action. Accepts 'attach' or 'detach'.
3803
-			 * @param int    $attachment_id The attachment ID.
3804
-			 * @param int    $parent_id     Attachment parent ID.
3805
-			 */
3806
-			do_action( 'wp_media_attach_action', $action, $attachment_id, $parent_id );
3807
-
3808
-			clean_attachment_cache( $attachment_id );
3809
-		}
3810
-
3811
-		$location = 'upload.php';
3812
-		$referer  = wp_get_referer();
3813
-
3814
-		if ( $referer ) {
3815
-			if ( false !== strpos( $referer, 'upload.php' ) ) {
3816
-				$location = remove_query_arg( array( 'attached', 'detach' ), $referer );
3817
-			}
3818
-		}
3819
-
3820
-		$key      = 'attach' === $action ? 'attached' : 'detach';
3821
-		$location = add_query_arg( array( $key => $result ), $location );
3822
-
3823
-		wp_redirect( $location );
3824
-		exit;
3825
-	}
3763
+    global $wpdb;
3764
+
3765
+    if ( ! $parent_id ) {
3766
+        return;
3767
+    }
3768
+
3769
+    if ( ! current_user_can( 'edit_post', $parent_id ) ) {
3770
+        wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
3771
+    }
3772
+
3773
+    $ids = array();
3774
+
3775
+    foreach ( (array) $_REQUEST['media'] as $attachment_id ) {
3776
+        $attachment_id = (int) $attachment_id;
3777
+
3778
+        if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
3779
+            continue;
3780
+        }
3781
+
3782
+        $ids[] = $attachment_id;
3783
+    }
3784
+
3785
+    if ( ! empty( $ids ) ) {
3786
+        $ids_string = implode( ',', $ids );
3787
+
3788
+        if ( 'attach' === $action ) {
3789
+            $result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $ids_string )", $parent_id ) );
3790
+        } else {
3791
+            $result = $wpdb->query( "UPDATE $wpdb->posts SET post_parent = 0 WHERE post_type = 'attachment' AND ID IN ( $ids_string )" );
3792
+        }
3793
+    }
3794
+
3795
+    if ( isset( $result ) ) {
3796
+        foreach ( $ids as $attachment_id ) {
3797
+            /**
3798
+             * Fires when media is attached or detached from a post.
3799
+             *
3800
+             * @since 5.5.0
3801
+             *
3802
+             * @param string $action        Attach/detach action. Accepts 'attach' or 'detach'.
3803
+             * @param int    $attachment_id The attachment ID.
3804
+             * @param int    $parent_id     Attachment parent ID.
3805
+             */
3806
+            do_action( 'wp_media_attach_action', $action, $attachment_id, $parent_id );
3807
+
3808
+            clean_attachment_cache( $attachment_id );
3809
+        }
3810
+
3811
+        $location = 'upload.php';
3812
+        $referer  = wp_get_referer();
3813
+
3814
+        if ( $referer ) {
3815
+            if ( false !== strpos( $referer, 'upload.php' ) ) {
3816
+                $location = remove_query_arg( array( 'attached', 'detach' ), $referer );
3817
+            }
3818
+        }
3819
+
3820
+        $key      = 'attach' === $action ? 'attached' : 'detach';
3821
+        $location = add_query_arg( array( $key => $result ), $location );
3822
+
3823
+        wp_redirect( $location );
3824
+        exit;
3825
+    }
3826 3826
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/update-core.php 1 patch
Indentation   +1492 added lines, -1492 removed lines patch added patch discarded remove patch
@@ -19,832 +19,832 @@  discard block
 block discarded – undo
19 19
 global $_old_files;
20 20
 
21 21
 $_old_files = array(
22
-	// 2.0
23
-	'wp-admin/import-b2.php',
24
-	'wp-admin/import-blogger.php',
25
-	'wp-admin/import-greymatter.php',
26
-	'wp-admin/import-livejournal.php',
27
-	'wp-admin/import-mt.php',
28
-	'wp-admin/import-rss.php',
29
-	'wp-admin/import-textpattern.php',
30
-	'wp-admin/quicktags.js',
31
-	'wp-images/fade-butt.png',
32
-	'wp-images/get-firefox.png',
33
-	'wp-images/header-shadow.png',
34
-	'wp-images/smilies',
35
-	'wp-images/wp-small.png',
36
-	'wp-images/wpminilogo.png',
37
-	'wp.php',
38
-	// 2.0.8
39
-	'wp-includes/js/tinymce/plugins/inlinepopups/readme.txt',
40
-	// 2.1
41
-	'wp-admin/edit-form-ajax-cat.php',
42
-	'wp-admin/execute-pings.php',
43
-	'wp-admin/inline-uploading.php',
44
-	'wp-admin/link-categories.php',
45
-	'wp-admin/list-manipulation.js',
46
-	'wp-admin/list-manipulation.php',
47
-	'wp-includes/comment-functions.php',
48
-	'wp-includes/feed-functions.php',
49
-	'wp-includes/functions-compat.php',
50
-	'wp-includes/functions-formatting.php',
51
-	'wp-includes/functions-post.php',
52
-	'wp-includes/js/dbx-key.js',
53
-	'wp-includes/js/tinymce/plugins/autosave/langs/cs.js',
54
-	'wp-includes/js/tinymce/plugins/autosave/langs/sv.js',
55
-	'wp-includes/links.php',
56
-	'wp-includes/pluggable-functions.php',
57
-	'wp-includes/template-functions-author.php',
58
-	'wp-includes/template-functions-category.php',
59
-	'wp-includes/template-functions-general.php',
60
-	'wp-includes/template-functions-links.php',
61
-	'wp-includes/template-functions-post.php',
62
-	'wp-includes/wp-l10n.php',
63
-	// 2.2
64
-	'wp-admin/cat-js.php',
65
-	'wp-admin/import/b2.php',
66
-	'wp-includes/js/autosave-js.php',
67
-	'wp-includes/js/list-manipulation-js.php',
68
-	'wp-includes/js/wp-ajax-js.php',
69
-	// 2.3
70
-	'wp-admin/admin-db.php',
71
-	'wp-admin/cat.js',
72
-	'wp-admin/categories.js',
73
-	'wp-admin/custom-fields.js',
74
-	'wp-admin/dbx-admin-key.js',
75
-	'wp-admin/edit-comments.js',
76
-	'wp-admin/install-rtl.css',
77
-	'wp-admin/install.css',
78
-	'wp-admin/upgrade-schema.php',
79
-	'wp-admin/upload-functions.php',
80
-	'wp-admin/upload-rtl.css',
81
-	'wp-admin/upload.css',
82
-	'wp-admin/upload.js',
83
-	'wp-admin/users.js',
84
-	'wp-admin/widgets-rtl.css',
85
-	'wp-admin/widgets.css',
86
-	'wp-admin/xfn.js',
87
-	'wp-includes/js/tinymce/license.html',
88
-	// 2.5
89
-	'wp-admin/css/upload.css',
90
-	'wp-admin/images/box-bg-left.gif',
91
-	'wp-admin/images/box-bg-right.gif',
92
-	'wp-admin/images/box-bg.gif',
93
-	'wp-admin/images/box-butt-left.gif',
94
-	'wp-admin/images/box-butt-right.gif',
95
-	'wp-admin/images/box-butt.gif',
96
-	'wp-admin/images/box-head-left.gif',
97
-	'wp-admin/images/box-head-right.gif',
98
-	'wp-admin/images/box-head.gif',
99
-	'wp-admin/images/heading-bg.gif',
100
-	'wp-admin/images/login-bkg-bottom.gif',
101
-	'wp-admin/images/login-bkg-tile.gif',
102
-	'wp-admin/images/notice.gif',
103
-	'wp-admin/images/toggle.gif',
104
-	'wp-admin/includes/upload.php',
105
-	'wp-admin/js/dbx-admin-key.js',
106
-	'wp-admin/js/link-cat.js',
107
-	'wp-admin/profile-update.php',
108
-	'wp-admin/templates.php',
109
-	'wp-includes/images/wlw/WpComments.png',
110
-	'wp-includes/images/wlw/WpIcon.png',
111
-	'wp-includes/images/wlw/WpWatermark.png',
112
-	'wp-includes/js/dbx.js',
113
-	'wp-includes/js/fat.js',
114
-	'wp-includes/js/list-manipulation.js',
115
-	'wp-includes/js/tinymce/langs/en.js',
116
-	'wp-includes/js/tinymce/plugins/autosave/editor_plugin_src.js',
117
-	'wp-includes/js/tinymce/plugins/autosave/langs',
118
-	'wp-includes/js/tinymce/plugins/directionality/images',
119
-	'wp-includes/js/tinymce/plugins/directionality/langs',
120
-	'wp-includes/js/tinymce/plugins/inlinepopups/css',
121
-	'wp-includes/js/tinymce/plugins/inlinepopups/images',
122
-	'wp-includes/js/tinymce/plugins/inlinepopups/jscripts',
123
-	'wp-includes/js/tinymce/plugins/paste/images',
124
-	'wp-includes/js/tinymce/plugins/paste/jscripts',
125
-	'wp-includes/js/tinymce/plugins/paste/langs',
126
-	'wp-includes/js/tinymce/plugins/spellchecker/classes/HttpClient.class.php',
127
-	'wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php',
128
-	'wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspell.class.php',
129
-	'wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php',
130
-	'wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css',
131
-	'wp-includes/js/tinymce/plugins/spellchecker/images',
132
-	'wp-includes/js/tinymce/plugins/spellchecker/langs',
133
-	'wp-includes/js/tinymce/plugins/spellchecker/tinyspell.php',
134
-	'wp-includes/js/tinymce/plugins/wordpress/images',
135
-	'wp-includes/js/tinymce/plugins/wordpress/langs',
136
-	'wp-includes/js/tinymce/plugins/wordpress/wordpress.css',
137
-	'wp-includes/js/tinymce/plugins/wphelp',
138
-	'wp-includes/js/tinymce/themes/advanced/css',
139
-	'wp-includes/js/tinymce/themes/advanced/images',
140
-	'wp-includes/js/tinymce/themes/advanced/jscripts',
141
-	'wp-includes/js/tinymce/themes/advanced/langs',
142
-	// 2.5.1
143
-	'wp-includes/js/tinymce/tiny_mce_gzip.php',
144
-	// 2.6
145
-	'wp-admin/bookmarklet.php',
146
-	'wp-includes/js/jquery/jquery.dimensions.min.js',
147
-	'wp-includes/js/tinymce/plugins/wordpress/popups.css',
148
-	'wp-includes/js/wp-ajax.js',
149
-	// 2.7
150
-	'wp-admin/css/press-this-ie-rtl.css',
151
-	'wp-admin/css/press-this-ie.css',
152
-	'wp-admin/css/upload-rtl.css',
153
-	'wp-admin/edit-form.php',
154
-	'wp-admin/images/comment-pill.gif',
155
-	'wp-admin/images/comment-stalk-classic.gif',
156
-	'wp-admin/images/comment-stalk-fresh.gif',
157
-	'wp-admin/images/comment-stalk-rtl.gif',
158
-	'wp-admin/images/del.png',
159
-	'wp-admin/images/gear.png',
160
-	'wp-admin/images/media-button-gallery.gif',
161
-	'wp-admin/images/media-buttons.gif',
162
-	'wp-admin/images/postbox-bg.gif',
163
-	'wp-admin/images/tab.png',
164
-	'wp-admin/images/tail.gif',
165
-	'wp-admin/js/forms.js',
166
-	'wp-admin/js/upload.js',
167
-	'wp-admin/link-import.php',
168
-	'wp-includes/images/audio.png',
169
-	'wp-includes/images/css.png',
170
-	'wp-includes/images/default.png',
171
-	'wp-includes/images/doc.png',
172
-	'wp-includes/images/exe.png',
173
-	'wp-includes/images/html.png',
174
-	'wp-includes/images/js.png',
175
-	'wp-includes/images/pdf.png',
176
-	'wp-includes/images/swf.png',
177
-	'wp-includes/images/tar.png',
178
-	'wp-includes/images/text.png',
179
-	'wp-includes/images/video.png',
180
-	'wp-includes/images/zip.png',
181
-	'wp-includes/js/tinymce/tiny_mce_config.php',
182
-	'wp-includes/js/tinymce/tiny_mce_ext.js',
183
-	// 2.8
184
-	'wp-admin/js/users.js',
185
-	'wp-includes/js/swfupload/plugins/swfupload.documentready.js',
186
-	'wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js',
187
-	'wp-includes/js/swfupload/swfupload_f9.swf',
188
-	'wp-includes/js/tinymce/plugins/autosave',
189
-	'wp-includes/js/tinymce/plugins/paste/css',
190
-	'wp-includes/js/tinymce/utils/mclayer.js',
191
-	'wp-includes/js/tinymce/wordpress.css',
192
-	// 2.8.5
193
-	'wp-admin/import/btt.php',
194
-	'wp-admin/import/jkw.php',
195
-	// 2.9
196
-	'wp-admin/js/page.dev.js',
197
-	'wp-admin/js/page.js',
198
-	'wp-admin/js/set-post-thumbnail-handler.dev.js',
199
-	'wp-admin/js/set-post-thumbnail-handler.js',
200
-	'wp-admin/js/slug.dev.js',
201
-	'wp-admin/js/slug.js',
202
-	'wp-includes/gettext.php',
203
-	'wp-includes/js/tinymce/plugins/wordpress/js',
204
-	'wp-includes/streams.php',
205
-	// MU
206
-	'README.txt',
207
-	'htaccess.dist',
208
-	'index-install.php',
209
-	'wp-admin/css/mu-rtl.css',
210
-	'wp-admin/css/mu.css',
211
-	'wp-admin/images/site-admin.png',
212
-	'wp-admin/includes/mu.php',
213
-	'wp-admin/wpmu-admin.php',
214
-	'wp-admin/wpmu-blogs.php',
215
-	'wp-admin/wpmu-edit.php',
216
-	'wp-admin/wpmu-options.php',
217
-	'wp-admin/wpmu-themes.php',
218
-	'wp-admin/wpmu-upgrade-site.php',
219
-	'wp-admin/wpmu-users.php',
220
-	'wp-includes/images/wordpress-mu.png',
221
-	'wp-includes/wpmu-default-filters.php',
222
-	'wp-includes/wpmu-functions.php',
223
-	'wpmu-settings.php',
224
-	// 3.0
225
-	'wp-admin/categories.php',
226
-	'wp-admin/edit-category-form.php',
227
-	'wp-admin/edit-page-form.php',
228
-	'wp-admin/edit-pages.php',
229
-	'wp-admin/images/admin-header-footer.png',
230
-	'wp-admin/images/browse-happy.gif',
231
-	'wp-admin/images/ico-add.png',
232
-	'wp-admin/images/ico-close.png',
233
-	'wp-admin/images/ico-edit.png',
234
-	'wp-admin/images/ico-viewpage.png',
235
-	'wp-admin/images/fav-top.png',
236
-	'wp-admin/images/screen-options-left.gif',
237
-	'wp-admin/images/wp-logo-vs.gif',
238
-	'wp-admin/images/wp-logo.gif',
239
-	'wp-admin/import',
240
-	'wp-admin/js/wp-gears.dev.js',
241
-	'wp-admin/js/wp-gears.js',
242
-	'wp-admin/options-misc.php',
243
-	'wp-admin/page-new.php',
244
-	'wp-admin/page.php',
245
-	'wp-admin/rtl.css',
246
-	'wp-admin/rtl.dev.css',
247
-	'wp-admin/update-links.php',
248
-	'wp-admin/wp-admin.css',
249
-	'wp-admin/wp-admin.dev.css',
250
-	'wp-includes/js/codepress',
251
-	'wp-includes/js/codepress/engines/khtml.js',
252
-	'wp-includes/js/codepress/engines/older.js',
253
-	'wp-includes/js/jquery/autocomplete.dev.js',
254
-	'wp-includes/js/jquery/autocomplete.js',
255
-	'wp-includes/js/jquery/interface.js',
256
-	'wp-includes/js/scriptaculous/prototype.js',
257
-	// Following file added back in 5.1, see #45645.
258
-	//'wp-includes/js/tinymce/wp-tinymce.js',
259
-	// 3.1
260
-	'wp-admin/edit-attachment-rows.php',
261
-	'wp-admin/edit-link-categories.php',
262
-	'wp-admin/edit-link-category-form.php',
263
-	'wp-admin/edit-post-rows.php',
264
-	'wp-admin/images/button-grad-active-vs.png',
265
-	'wp-admin/images/button-grad-vs.png',
266
-	'wp-admin/images/fav-arrow-vs-rtl.gif',
267
-	'wp-admin/images/fav-arrow-vs.gif',
268
-	'wp-admin/images/fav-top-vs.gif',
269
-	'wp-admin/images/list-vs.png',
270
-	'wp-admin/images/screen-options-right-up.gif',
271
-	'wp-admin/images/screen-options-right.gif',
272
-	'wp-admin/images/visit-site-button-grad-vs.gif',
273
-	'wp-admin/images/visit-site-button-grad.gif',
274
-	'wp-admin/link-category.php',
275
-	'wp-admin/sidebar.php',
276
-	'wp-includes/classes.php',
277
-	'wp-includes/js/tinymce/blank.htm',
278
-	'wp-includes/js/tinymce/plugins/media/css/content.css',
279
-	'wp-includes/js/tinymce/plugins/media/img',
280
-	'wp-includes/js/tinymce/plugins/safari',
281
-	// 3.2
282
-	'wp-admin/images/logo-login.gif',
283
-	'wp-admin/images/star.gif',
284
-	'wp-admin/js/list-table.dev.js',
285
-	'wp-admin/js/list-table.js',
286
-	'wp-includes/default-embeds.php',
287
-	'wp-includes/js/tinymce/plugins/wordpress/img/help.gif',
288
-	'wp-includes/js/tinymce/plugins/wordpress/img/more.gif',
289
-	'wp-includes/js/tinymce/plugins/wordpress/img/toolbars.gif',
290
-	'wp-includes/js/tinymce/themes/advanced/img/fm.gif',
291
-	'wp-includes/js/tinymce/themes/advanced/img/sflogo.png',
292
-	// 3.3
293
-	'wp-admin/css/colors-classic-rtl.css',
294
-	'wp-admin/css/colors-classic-rtl.dev.css',
295
-	'wp-admin/css/colors-fresh-rtl.css',
296
-	'wp-admin/css/colors-fresh-rtl.dev.css',
297
-	'wp-admin/css/dashboard-rtl.dev.css',
298
-	'wp-admin/css/dashboard.dev.css',
299
-	'wp-admin/css/global-rtl.css',
300
-	'wp-admin/css/global-rtl.dev.css',
301
-	'wp-admin/css/global.css',
302
-	'wp-admin/css/global.dev.css',
303
-	'wp-admin/css/install-rtl.dev.css',
304
-	'wp-admin/css/login-rtl.dev.css',
305
-	'wp-admin/css/login.dev.css',
306
-	'wp-admin/css/ms.css',
307
-	'wp-admin/css/ms.dev.css',
308
-	'wp-admin/css/nav-menu-rtl.css',
309
-	'wp-admin/css/nav-menu-rtl.dev.css',
310
-	'wp-admin/css/nav-menu.css',
311
-	'wp-admin/css/nav-menu.dev.css',
312
-	'wp-admin/css/plugin-install-rtl.css',
313
-	'wp-admin/css/plugin-install-rtl.dev.css',
314
-	'wp-admin/css/plugin-install.css',
315
-	'wp-admin/css/plugin-install.dev.css',
316
-	'wp-admin/css/press-this-rtl.dev.css',
317
-	'wp-admin/css/press-this.dev.css',
318
-	'wp-admin/css/theme-editor-rtl.css',
319
-	'wp-admin/css/theme-editor-rtl.dev.css',
320
-	'wp-admin/css/theme-editor.css',
321
-	'wp-admin/css/theme-editor.dev.css',
322
-	'wp-admin/css/theme-install-rtl.css',
323
-	'wp-admin/css/theme-install-rtl.dev.css',
324
-	'wp-admin/css/theme-install.css',
325
-	'wp-admin/css/theme-install.dev.css',
326
-	'wp-admin/css/widgets-rtl.dev.css',
327
-	'wp-admin/css/widgets.dev.css',
328
-	'wp-admin/includes/internal-linking.php',
329
-	'wp-includes/images/admin-bar-sprite-rtl.png',
330
-	'wp-includes/js/jquery/ui.button.js',
331
-	'wp-includes/js/jquery/ui.core.js',
332
-	'wp-includes/js/jquery/ui.dialog.js',
333
-	'wp-includes/js/jquery/ui.draggable.js',
334
-	'wp-includes/js/jquery/ui.droppable.js',
335
-	'wp-includes/js/jquery/ui.mouse.js',
336
-	'wp-includes/js/jquery/ui.position.js',
337
-	'wp-includes/js/jquery/ui.resizable.js',
338
-	'wp-includes/js/jquery/ui.selectable.js',
339
-	'wp-includes/js/jquery/ui.sortable.js',
340
-	'wp-includes/js/jquery/ui.tabs.js',
341
-	'wp-includes/js/jquery/ui.widget.js',
342
-	'wp-includes/js/l10n.dev.js',
343
-	'wp-includes/js/l10n.js',
344
-	'wp-includes/js/tinymce/plugins/wplink/css',
345
-	'wp-includes/js/tinymce/plugins/wplink/img',
346
-	'wp-includes/js/tinymce/plugins/wplink/js',
347
-	'wp-includes/js/tinymce/themes/advanced/img/wpicons.png',
348
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/butt2.png',
349
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/button_bg.png',
350
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/down_arrow.gif',
351
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/fade-butt.png',
352
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/separator.gif',
353
-	// Don't delete, yet: 'wp-rss.php',
354
-	// Don't delete, yet: 'wp-rdf.php',
355
-	// Don't delete, yet: 'wp-rss2.php',
356
-	// Don't delete, yet: 'wp-commentsrss2.php',
357
-	// Don't delete, yet: 'wp-atom.php',
358
-	// Don't delete, yet: 'wp-feed.php',
359
-	// 3.4
360
-	'wp-admin/images/gray-star.png',
361
-	'wp-admin/images/logo-login.png',
362
-	'wp-admin/images/star.png',
363
-	'wp-admin/index-extra.php',
364
-	'wp-admin/network/index-extra.php',
365
-	'wp-admin/user/index-extra.php',
366
-	'wp-admin/images/screenshots/admin-flyouts.png',
367
-	'wp-admin/images/screenshots/coediting.png',
368
-	'wp-admin/images/screenshots/drag-and-drop.png',
369
-	'wp-admin/images/screenshots/help-screen.png',
370
-	'wp-admin/images/screenshots/media-icon.png',
371
-	'wp-admin/images/screenshots/new-feature-pointer.png',
372
-	'wp-admin/images/screenshots/welcome-screen.png',
373
-	'wp-includes/css/editor-buttons.css',
374
-	'wp-includes/css/editor-buttons.dev.css',
375
-	'wp-includes/js/tinymce/plugins/paste/blank.htm',
376
-	'wp-includes/js/tinymce/plugins/wordpress/css',
377
-	'wp-includes/js/tinymce/plugins/wordpress/editor_plugin.dev.js',
378
-	'wp-includes/js/tinymce/plugins/wordpress/img/embedded.png',
379
-	'wp-includes/js/tinymce/plugins/wordpress/img/more_bug.gif',
380
-	'wp-includes/js/tinymce/plugins/wordpress/img/page_bug.gif',
381
-	'wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js',
382
-	'wp-includes/js/tinymce/plugins/wpeditimage/css/editimage-rtl.css',
383
-	'wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.dev.js',
384
-	'wp-includes/js/tinymce/plugins/wpfullscreen/editor_plugin.dev.js',
385
-	'wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.dev.js',
386
-	'wp-includes/js/tinymce/plugins/wpgallery/img/gallery.png',
387
-	'wp-includes/js/tinymce/plugins/wplink/editor_plugin.dev.js',
388
-	// Don't delete, yet: 'wp-pass.php',
389
-	// Don't delete, yet: 'wp-register.php',
390
-	// 3.5
391
-	'wp-admin/gears-manifest.php',
392
-	'wp-admin/includes/manifest.php',
393
-	'wp-admin/images/archive-link.png',
394
-	'wp-admin/images/blue-grad.png',
395
-	'wp-admin/images/button-grad-active.png',
396
-	'wp-admin/images/button-grad.png',
397
-	'wp-admin/images/ed-bg-vs.gif',
398
-	'wp-admin/images/ed-bg.gif',
399
-	'wp-admin/images/fade-butt.png',
400
-	'wp-admin/images/fav-arrow-rtl.gif',
401
-	'wp-admin/images/fav-arrow.gif',
402
-	'wp-admin/images/fav-vs.png',
403
-	'wp-admin/images/fav.png',
404
-	'wp-admin/images/gray-grad.png',
405
-	'wp-admin/images/loading-publish.gif',
406
-	'wp-admin/images/logo-ghost.png',
407
-	'wp-admin/images/logo.gif',
408
-	'wp-admin/images/menu-arrow-frame-rtl.png',
409
-	'wp-admin/images/menu-arrow-frame.png',
410
-	'wp-admin/images/menu-arrows.gif',
411
-	'wp-admin/images/menu-bits-rtl-vs.gif',
412
-	'wp-admin/images/menu-bits-rtl.gif',
413
-	'wp-admin/images/menu-bits-vs.gif',
414
-	'wp-admin/images/menu-bits.gif',
415
-	'wp-admin/images/menu-dark-rtl-vs.gif',
416
-	'wp-admin/images/menu-dark-rtl.gif',
417
-	'wp-admin/images/menu-dark-vs.gif',
418
-	'wp-admin/images/menu-dark.gif',
419
-	'wp-admin/images/required.gif',
420
-	'wp-admin/images/screen-options-toggle-vs.gif',
421
-	'wp-admin/images/screen-options-toggle.gif',
422
-	'wp-admin/images/toggle-arrow-rtl.gif',
423
-	'wp-admin/images/toggle-arrow.gif',
424
-	'wp-admin/images/upload-classic.png',
425
-	'wp-admin/images/upload-fresh.png',
426
-	'wp-admin/images/white-grad-active.png',
427
-	'wp-admin/images/white-grad.png',
428
-	'wp-admin/images/widgets-arrow-vs.gif',
429
-	'wp-admin/images/widgets-arrow.gif',
430
-	'wp-admin/images/wpspin_dark.gif',
431
-	'wp-includes/images/upload.png',
432
-	'wp-includes/js/prototype.js',
433
-	'wp-includes/js/scriptaculous',
434
-	'wp-admin/css/wp-admin-rtl.dev.css',
435
-	'wp-admin/css/wp-admin.dev.css',
436
-	'wp-admin/css/media-rtl.dev.css',
437
-	'wp-admin/css/media.dev.css',
438
-	'wp-admin/css/colors-classic.dev.css',
439
-	'wp-admin/css/customize-controls-rtl.dev.css',
440
-	'wp-admin/css/customize-controls.dev.css',
441
-	'wp-admin/css/ie-rtl.dev.css',
442
-	'wp-admin/css/ie.dev.css',
443
-	'wp-admin/css/install.dev.css',
444
-	'wp-admin/css/colors-fresh.dev.css',
445
-	'wp-includes/js/customize-base.dev.js',
446
-	'wp-includes/js/json2.dev.js',
447
-	'wp-includes/js/comment-reply.dev.js',
448
-	'wp-includes/js/customize-preview.dev.js',
449
-	'wp-includes/js/wplink.dev.js',
450
-	'wp-includes/js/tw-sack.dev.js',
451
-	'wp-includes/js/wp-list-revisions.dev.js',
452
-	'wp-includes/js/autosave.dev.js',
453
-	'wp-includes/js/admin-bar.dev.js',
454
-	'wp-includes/js/quicktags.dev.js',
455
-	'wp-includes/js/wp-ajax-response.dev.js',
456
-	'wp-includes/js/wp-pointer.dev.js',
457
-	'wp-includes/js/hoverIntent.dev.js',
458
-	'wp-includes/js/colorpicker.dev.js',
459
-	'wp-includes/js/wp-lists.dev.js',
460
-	'wp-includes/js/customize-loader.dev.js',
461
-	'wp-includes/js/jquery/jquery.table-hotkeys.dev.js',
462
-	'wp-includes/js/jquery/jquery.color.dev.js',
463
-	'wp-includes/js/jquery/jquery.color.js',
464
-	'wp-includes/js/jquery/jquery.hotkeys.dev.js',
465
-	'wp-includes/js/jquery/jquery.form.dev.js',
466
-	'wp-includes/js/jquery/suggest.dev.js',
467
-	'wp-admin/js/xfn.dev.js',
468
-	'wp-admin/js/set-post-thumbnail.dev.js',
469
-	'wp-admin/js/comment.dev.js',
470
-	'wp-admin/js/theme.dev.js',
471
-	'wp-admin/js/cat.dev.js',
472
-	'wp-admin/js/password-strength-meter.dev.js',
473
-	'wp-admin/js/user-profile.dev.js',
474
-	'wp-admin/js/theme-preview.dev.js',
475
-	'wp-admin/js/post.dev.js',
476
-	'wp-admin/js/media-upload.dev.js',
477
-	'wp-admin/js/word-count.dev.js',
478
-	'wp-admin/js/plugin-install.dev.js',
479
-	'wp-admin/js/edit-comments.dev.js',
480
-	'wp-admin/js/media-gallery.dev.js',
481
-	'wp-admin/js/custom-fields.dev.js',
482
-	'wp-admin/js/custom-background.dev.js',
483
-	'wp-admin/js/common.dev.js',
484
-	'wp-admin/js/inline-edit-tax.dev.js',
485
-	'wp-admin/js/gallery.dev.js',
486
-	'wp-admin/js/utils.dev.js',
487
-	'wp-admin/js/widgets.dev.js',
488
-	'wp-admin/js/wp-fullscreen.dev.js',
489
-	'wp-admin/js/nav-menu.dev.js',
490
-	'wp-admin/js/dashboard.dev.js',
491
-	'wp-admin/js/link.dev.js',
492
-	'wp-admin/js/user-suggest.dev.js',
493
-	'wp-admin/js/postbox.dev.js',
494
-	'wp-admin/js/tags.dev.js',
495
-	'wp-admin/js/image-edit.dev.js',
496
-	'wp-admin/js/media.dev.js',
497
-	'wp-admin/js/customize-controls.dev.js',
498
-	'wp-admin/js/inline-edit-post.dev.js',
499
-	'wp-admin/js/categories.dev.js',
500
-	'wp-admin/js/editor.dev.js',
501
-	'wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js',
502
-	'wp-includes/js/tinymce/plugins/wpdialogs/js/popup.dev.js',
503
-	'wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.dev.js',
504
-	'wp-includes/js/plupload/handlers.dev.js',
505
-	'wp-includes/js/plupload/wp-plupload.dev.js',
506
-	'wp-includes/js/swfupload/handlers.dev.js',
507
-	'wp-includes/js/jcrop/jquery.Jcrop.dev.js',
508
-	'wp-includes/js/jcrop/jquery.Jcrop.js',
509
-	'wp-includes/js/jcrop/jquery.Jcrop.css',
510
-	'wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js',
511
-	'wp-includes/css/wp-pointer.dev.css',
512
-	'wp-includes/css/editor.dev.css',
513
-	'wp-includes/css/jquery-ui-dialog.dev.css',
514
-	'wp-includes/css/admin-bar-rtl.dev.css',
515
-	'wp-includes/css/admin-bar.dev.css',
516
-	'wp-includes/js/jquery/ui/jquery.effects.clip.min.js',
517
-	'wp-includes/js/jquery/ui/jquery.effects.scale.min.js',
518
-	'wp-includes/js/jquery/ui/jquery.effects.blind.min.js',
519
-	'wp-includes/js/jquery/ui/jquery.effects.core.min.js',
520
-	'wp-includes/js/jquery/ui/jquery.effects.shake.min.js',
521
-	'wp-includes/js/jquery/ui/jquery.effects.fade.min.js',
522
-	'wp-includes/js/jquery/ui/jquery.effects.explode.min.js',
523
-	'wp-includes/js/jquery/ui/jquery.effects.slide.min.js',
524
-	'wp-includes/js/jquery/ui/jquery.effects.drop.min.js',
525
-	'wp-includes/js/jquery/ui/jquery.effects.highlight.min.js',
526
-	'wp-includes/js/jquery/ui/jquery.effects.bounce.min.js',
527
-	'wp-includes/js/jquery/ui/jquery.effects.pulsate.min.js',
528
-	'wp-includes/js/jquery/ui/jquery.effects.transfer.min.js',
529
-	'wp-includes/js/jquery/ui/jquery.effects.fold.min.js',
530
-	'wp-admin/images/screenshots/captions-1.png',
531
-	'wp-admin/images/screenshots/captions-2.png',
532
-	'wp-admin/images/screenshots/flex-header-1.png',
533
-	'wp-admin/images/screenshots/flex-header-2.png',
534
-	'wp-admin/images/screenshots/flex-header-3.png',
535
-	'wp-admin/images/screenshots/flex-header-media-library.png',
536
-	'wp-admin/images/screenshots/theme-customizer.png',
537
-	'wp-admin/images/screenshots/twitter-embed-1.png',
538
-	'wp-admin/images/screenshots/twitter-embed-2.png',
539
-	'wp-admin/js/utils.js',
540
-	// Added back in 5.3 [45448], see #43895.
541
-	// 'wp-admin/options-privacy.php',
542
-	'wp-app.php',
543
-	'wp-includes/class-wp-atom-server.php',
544
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/ui.css',
545
-	// 3.5.2
546
-	'wp-includes/js/swfupload/swfupload-all.js',
547
-	// 3.6
548
-	'wp-admin/js/revisions-js.php',
549
-	'wp-admin/images/screenshots',
550
-	'wp-admin/js/categories.js',
551
-	'wp-admin/js/categories.min.js',
552
-	'wp-admin/js/custom-fields.js',
553
-	'wp-admin/js/custom-fields.min.js',
554
-	// 3.7
555
-	'wp-admin/js/cat.js',
556
-	'wp-admin/js/cat.min.js',
557
-	'wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.min.js',
558
-	// 3.8
559
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/page_bug.gif',
560
-	'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/more_bug.gif',
561
-	'wp-includes/js/thickbox/tb-close-2x.png',
562
-	'wp-includes/js/thickbox/tb-close.png',
563
-	'wp-includes/images/wpmini-blue-2x.png',
564
-	'wp-includes/images/wpmini-blue.png',
565
-	'wp-admin/css/colors-fresh.css',
566
-	'wp-admin/css/colors-classic.css',
567
-	'wp-admin/css/colors-fresh.min.css',
568
-	'wp-admin/css/colors-classic.min.css',
569
-	'wp-admin/js/about.min.js',
570
-	'wp-admin/js/about.js',
571
-	'wp-admin/images/arrows-dark-vs-2x.png',
572
-	'wp-admin/images/wp-logo-vs.png',
573
-	'wp-admin/images/arrows-dark-vs.png',
574
-	'wp-admin/images/wp-logo.png',
575
-	'wp-admin/images/arrows-pr.png',
576
-	'wp-admin/images/arrows-dark.png',
577
-	'wp-admin/images/press-this.png',
578
-	'wp-admin/images/press-this-2x.png',
579
-	'wp-admin/images/arrows-vs-2x.png',
580
-	'wp-admin/images/welcome-icons.png',
581
-	'wp-admin/images/wp-logo-2x.png',
582
-	'wp-admin/images/stars-rtl-2x.png',
583
-	'wp-admin/images/arrows-dark-2x.png',
584
-	'wp-admin/images/arrows-pr-2x.png',
585
-	'wp-admin/images/menu-shadow-rtl.png',
586
-	'wp-admin/images/arrows-vs.png',
587
-	'wp-admin/images/about-search-2x.png',
588
-	'wp-admin/images/bubble_bg-rtl-2x.gif',
589
-	'wp-admin/images/wp-badge-2x.png',
590
-	'wp-admin/images/wordpress-logo-2x.png',
591
-	'wp-admin/images/bubble_bg-rtl.gif',
592
-	'wp-admin/images/wp-badge.png',
593
-	'wp-admin/images/menu-shadow.png',
594
-	'wp-admin/images/about-globe-2x.png',
595
-	'wp-admin/images/welcome-icons-2x.png',
596
-	'wp-admin/images/stars-rtl.png',
597
-	'wp-admin/images/wp-logo-vs-2x.png',
598
-	'wp-admin/images/about-updates-2x.png',
599
-	// 3.9
600
-	'wp-admin/css/colors.css',
601
-	'wp-admin/css/colors.min.css',
602
-	'wp-admin/css/colors-rtl.css',
603
-	'wp-admin/css/colors-rtl.min.css',
604
-	// Following files added back in 4.5, see #36083.
605
-	// 'wp-admin/css/media-rtl.min.css',
606
-	// 'wp-admin/css/media.min.css',
607
-	// 'wp-admin/css/farbtastic-rtl.min.css',
608
-	'wp-admin/images/lock-2x.png',
609
-	'wp-admin/images/lock.png',
610
-	'wp-admin/js/theme-preview.js',
611
-	'wp-admin/js/theme-install.min.js',
612
-	'wp-admin/js/theme-install.js',
613
-	'wp-admin/js/theme-preview.min.js',
614
-	'wp-includes/js/plupload/plupload.html4.js',
615
-	'wp-includes/js/plupload/plupload.html5.js',
616
-	'wp-includes/js/plupload/changelog.txt',
617
-	'wp-includes/js/plupload/plupload.silverlight.js',
618
-	'wp-includes/js/plupload/plupload.flash.js',
619
-	// Added back in 4.9 [41328], see #41755.
620
-	// 'wp-includes/js/plupload/plupload.js',
621
-	'wp-includes/js/tinymce/plugins/spellchecker',
622
-	'wp-includes/js/tinymce/plugins/inlinepopups',
623
-	'wp-includes/js/tinymce/plugins/media/js',
624
-	'wp-includes/js/tinymce/plugins/media/css',
625
-	'wp-includes/js/tinymce/plugins/wordpress/img',
626
-	'wp-includes/js/tinymce/plugins/wpdialogs/js',
627
-	'wp-includes/js/tinymce/plugins/wpeditimage/img',
628
-	'wp-includes/js/tinymce/plugins/wpeditimage/js',
629
-	'wp-includes/js/tinymce/plugins/wpeditimage/css',
630
-	'wp-includes/js/tinymce/plugins/wpgallery/img',
631
-	'wp-includes/js/tinymce/plugins/wpfullscreen/css',
632
-	'wp-includes/js/tinymce/plugins/paste/js',
633
-	'wp-includes/js/tinymce/themes/advanced',
634
-	'wp-includes/js/tinymce/tiny_mce.js',
635
-	'wp-includes/js/tinymce/mark_loaded_src.js',
636
-	'wp-includes/js/tinymce/wp-tinymce-schema.js',
637
-	'wp-includes/js/tinymce/plugins/media/editor_plugin.js',
638
-	'wp-includes/js/tinymce/plugins/media/editor_plugin_src.js',
639
-	'wp-includes/js/tinymce/plugins/media/media.htm',
640
-	'wp-includes/js/tinymce/plugins/wpview/editor_plugin_src.js',
641
-	'wp-includes/js/tinymce/plugins/wpview/editor_plugin.js',
642
-	'wp-includes/js/tinymce/plugins/directionality/editor_plugin.js',
643
-	'wp-includes/js/tinymce/plugins/directionality/editor_plugin_src.js',
644
-	'wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js',
645
-	'wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js',
646
-	'wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin_src.js',
647
-	'wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js',
648
-	'wp-includes/js/tinymce/plugins/wpeditimage/editimage.html',
649
-	'wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js',
650
-	'wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js',
651
-	'wp-includes/js/tinymce/plugins/fullscreen/editor_plugin_src.js',
652
-	'wp-includes/js/tinymce/plugins/fullscreen/fullscreen.htm',
653
-	'wp-includes/js/tinymce/plugins/fullscreen/editor_plugin.js',
654
-	'wp-includes/js/tinymce/plugins/wplink/editor_plugin_src.js',
655
-	'wp-includes/js/tinymce/plugins/wplink/editor_plugin.js',
656
-	'wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js',
657
-	'wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.js',
658
-	'wp-includes/js/tinymce/plugins/tabfocus/editor_plugin.js',
659
-	'wp-includes/js/tinymce/plugins/tabfocus/editor_plugin_src.js',
660
-	'wp-includes/js/tinymce/plugins/wpfullscreen/editor_plugin.js',
661
-	'wp-includes/js/tinymce/plugins/wpfullscreen/editor_plugin_src.js',
662
-	'wp-includes/js/tinymce/plugins/paste/editor_plugin.js',
663
-	'wp-includes/js/tinymce/plugins/paste/pasteword.htm',
664
-	'wp-includes/js/tinymce/plugins/paste/editor_plugin_src.js',
665
-	'wp-includes/js/tinymce/plugins/paste/pastetext.htm',
666
-	'wp-includes/js/tinymce/langs/wp-langs.php',
667
-	// 4.1
668
-	'wp-includes/js/jquery/ui/jquery.ui.accordion.min.js',
669
-	'wp-includes/js/jquery/ui/jquery.ui.autocomplete.min.js',
670
-	'wp-includes/js/jquery/ui/jquery.ui.button.min.js',
671
-	'wp-includes/js/jquery/ui/jquery.ui.core.min.js',
672
-	'wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js',
673
-	'wp-includes/js/jquery/ui/jquery.ui.dialog.min.js',
674
-	'wp-includes/js/jquery/ui/jquery.ui.draggable.min.js',
675
-	'wp-includes/js/jquery/ui/jquery.ui.droppable.min.js',
676
-	'wp-includes/js/jquery/ui/jquery.ui.effect-blind.min.js',
677
-	'wp-includes/js/jquery/ui/jquery.ui.effect-bounce.min.js',
678
-	'wp-includes/js/jquery/ui/jquery.ui.effect-clip.min.js',
679
-	'wp-includes/js/jquery/ui/jquery.ui.effect-drop.min.js',
680
-	'wp-includes/js/jquery/ui/jquery.ui.effect-explode.min.js',
681
-	'wp-includes/js/jquery/ui/jquery.ui.effect-fade.min.js',
682
-	'wp-includes/js/jquery/ui/jquery.ui.effect-fold.min.js',
683
-	'wp-includes/js/jquery/ui/jquery.ui.effect-highlight.min.js',
684
-	'wp-includes/js/jquery/ui/jquery.ui.effect-pulsate.min.js',
685
-	'wp-includes/js/jquery/ui/jquery.ui.effect-scale.min.js',
686
-	'wp-includes/js/jquery/ui/jquery.ui.effect-shake.min.js',
687
-	'wp-includes/js/jquery/ui/jquery.ui.effect-slide.min.js',
688
-	'wp-includes/js/jquery/ui/jquery.ui.effect-transfer.min.js',
689
-	'wp-includes/js/jquery/ui/jquery.ui.effect.min.js',
690
-	'wp-includes/js/jquery/ui/jquery.ui.menu.min.js',
691
-	'wp-includes/js/jquery/ui/jquery.ui.mouse.min.js',
692
-	'wp-includes/js/jquery/ui/jquery.ui.position.min.js',
693
-	'wp-includes/js/jquery/ui/jquery.ui.progressbar.min.js',
694
-	'wp-includes/js/jquery/ui/jquery.ui.resizable.min.js',
695
-	'wp-includes/js/jquery/ui/jquery.ui.selectable.min.js',
696
-	'wp-includes/js/jquery/ui/jquery.ui.slider.min.js',
697
-	'wp-includes/js/jquery/ui/jquery.ui.sortable.min.js',
698
-	'wp-includes/js/jquery/ui/jquery.ui.spinner.min.js',
699
-	'wp-includes/js/jquery/ui/jquery.ui.tabs.min.js',
700
-	'wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js',
701
-	'wp-includes/js/jquery/ui/jquery.ui.widget.min.js',
702
-	'wp-includes/js/tinymce/skins/wordpress/images/dashicon-no-alt.png',
703
-	// 4.3
704
-	'wp-admin/js/wp-fullscreen.js',
705
-	'wp-admin/js/wp-fullscreen.min.js',
706
-	'wp-includes/js/tinymce/wp-mce-help.php',
707
-	'wp-includes/js/tinymce/plugins/wpfullscreen',
708
-	// 4.5
709
-	'wp-includes/theme-compat/comments-popup.php',
710
-	// 4.6
711
-	'wp-admin/includes/class-wp-automatic-upgrader.php', // Wrong file name, see #37628.
712
-	// 4.8
713
-	'wp-includes/js/tinymce/plugins/wpembed',
714
-	'wp-includes/js/tinymce/plugins/media/moxieplayer.swf',
715
-	'wp-includes/js/tinymce/skins/lightgray/fonts/readme.md',
716
-	'wp-includes/js/tinymce/skins/lightgray/fonts/tinymce-small.json',
717
-	'wp-includes/js/tinymce/skins/lightgray/fonts/tinymce.json',
718
-	'wp-includes/js/tinymce/skins/lightgray/skin.ie7.min.css',
719
-	// 4.9
720
-	'wp-admin/css/press-this-editor-rtl.css',
721
-	'wp-admin/css/press-this-editor-rtl.min.css',
722
-	'wp-admin/css/press-this-editor.css',
723
-	'wp-admin/css/press-this-editor.min.css',
724
-	'wp-admin/css/press-this-rtl.css',
725
-	'wp-admin/css/press-this-rtl.min.css',
726
-	'wp-admin/css/press-this.css',
727
-	'wp-admin/css/press-this.min.css',
728
-	'wp-admin/includes/class-wp-press-this.php',
729
-	'wp-admin/js/bookmarklet.js',
730
-	'wp-admin/js/bookmarklet.min.js',
731
-	'wp-admin/js/press-this.js',
732
-	'wp-admin/js/press-this.min.js',
733
-	'wp-includes/js/mediaelement/background.png',
734
-	'wp-includes/js/mediaelement/bigplay.png',
735
-	'wp-includes/js/mediaelement/bigplay.svg',
736
-	'wp-includes/js/mediaelement/controls.png',
737
-	'wp-includes/js/mediaelement/controls.svg',
738
-	'wp-includes/js/mediaelement/flashmediaelement.swf',
739
-	'wp-includes/js/mediaelement/froogaloop.min.js',
740
-	'wp-includes/js/mediaelement/jumpforward.png',
741
-	'wp-includes/js/mediaelement/loading.gif',
742
-	'wp-includes/js/mediaelement/silverlightmediaelement.xap',
743
-	'wp-includes/js/mediaelement/skipback.png',
744
-	'wp-includes/js/plupload/plupload.flash.swf',
745
-	'wp-includes/js/plupload/plupload.full.min.js',
746
-	'wp-includes/js/plupload/plupload.silverlight.xap',
747
-	'wp-includes/js/swfupload/plugins',
748
-	'wp-includes/js/swfupload/swfupload.swf',
749
-	// 4.9.2
750
-	'wp-includes/js/mediaelement/lang',
751
-	'wp-includes/js/mediaelement/lang/ca.js',
752
-	'wp-includes/js/mediaelement/lang/cs.js',
753
-	'wp-includes/js/mediaelement/lang/de.js',
754
-	'wp-includes/js/mediaelement/lang/es.js',
755
-	'wp-includes/js/mediaelement/lang/fa.js',
756
-	'wp-includes/js/mediaelement/lang/fr.js',
757
-	'wp-includes/js/mediaelement/lang/hr.js',
758
-	'wp-includes/js/mediaelement/lang/hu.js',
759
-	'wp-includes/js/mediaelement/lang/it.js',
760
-	'wp-includes/js/mediaelement/lang/ja.js',
761
-	'wp-includes/js/mediaelement/lang/ko.js',
762
-	'wp-includes/js/mediaelement/lang/nl.js',
763
-	'wp-includes/js/mediaelement/lang/pl.js',
764
-	'wp-includes/js/mediaelement/lang/pt.js',
765
-	'wp-includes/js/mediaelement/lang/ro.js',
766
-	'wp-includes/js/mediaelement/lang/ru.js',
767
-	'wp-includes/js/mediaelement/lang/sk.js',
768
-	'wp-includes/js/mediaelement/lang/sv.js',
769
-	'wp-includes/js/mediaelement/lang/uk.js',
770
-	'wp-includes/js/mediaelement/lang/zh-cn.js',
771
-	'wp-includes/js/mediaelement/lang/zh.js',
772
-	'wp-includes/js/mediaelement/mediaelement-flash-audio-ogg.swf',
773
-	'wp-includes/js/mediaelement/mediaelement-flash-audio.swf',
774
-	'wp-includes/js/mediaelement/mediaelement-flash-video-hls.swf',
775
-	'wp-includes/js/mediaelement/mediaelement-flash-video-mdash.swf',
776
-	'wp-includes/js/mediaelement/mediaelement-flash-video.swf',
777
-	'wp-includes/js/mediaelement/renderers/dailymotion.js',
778
-	'wp-includes/js/mediaelement/renderers/dailymotion.min.js',
779
-	'wp-includes/js/mediaelement/renderers/facebook.js',
780
-	'wp-includes/js/mediaelement/renderers/facebook.min.js',
781
-	'wp-includes/js/mediaelement/renderers/soundcloud.js',
782
-	'wp-includes/js/mediaelement/renderers/soundcloud.min.js',
783
-	'wp-includes/js/mediaelement/renderers/twitch.js',
784
-	'wp-includes/js/mediaelement/renderers/twitch.min.js',
785
-	// 5.0
786
-	'wp-includes/js/codemirror/jshint.js',
787
-	// 5.1
788
-	'wp-includes/random_compat/random_bytes_openssl.php',
789
-	'wp-includes/js/tinymce/wp-tinymce.js.gz',
790
-	// 5.3
791
-	'wp-includes/js/wp-a11y.js',     // Moved to: wp-includes/js/dist/a11y.js
792
-	'wp-includes/js/wp-a11y.min.js', // Moved to: wp-includes/js/dist/a11y.min.js
793
-	// 5.4
794
-	'wp-admin/js/wp-fullscreen-stub.js',
795
-	'wp-admin/js/wp-fullscreen-stub.min.js',
796
-	// 5.5
797
-	'wp-admin/css/ie.css',
798
-	'wp-admin/css/ie.min.css',
799
-	'wp-admin/css/ie-rtl.css',
800
-	'wp-admin/css/ie-rtl.min.css',
801
-	// 5.6
802
-	'wp-includes/js/jquery/ui/position.min.js',
803
-	'wp-includes/js/jquery/ui/widget.min.js',
804
-	// 5.7
805
-	'wp-includes/blocks/classic/block.json',
806
-	// 5.8
807
-	'wp-admin/images/freedoms.png',
808
-	'wp-admin/images/privacy.png',
809
-	'wp-admin/images/about-badge.svg',
810
-	'wp-admin/images/about-color-palette.svg',
811
-	'wp-admin/images/about-color-palette-vert.svg',
812
-	'wp-admin/images/about-header-brushes.svg',
813
-	'wp-includes/block-patterns/large-header.php',
814
-	'wp-includes/block-patterns/heading-paragraph.php',
815
-	'wp-includes/block-patterns/quote.php',
816
-	'wp-includes/block-patterns/text-three-columns-buttons.php',
817
-	'wp-includes/block-patterns/two-buttons.php',
818
-	'wp-includes/block-patterns/two-images.php',
819
-	'wp-includes/block-patterns/three-buttons.php',
820
-	'wp-includes/block-patterns/text-two-columns-with-images.php',
821
-	'wp-includes/block-patterns/text-two-columns.php',
822
-	'wp-includes/block-patterns/large-header-button.php',
823
-	'wp-includes/blocks/subhead/block.json',
824
-	'wp-includes/blocks/subhead',
825
-	'wp-includes/css/dist/editor/editor-styles.css',
826
-	'wp-includes/css/dist/editor/editor-styles.min.css',
827
-	'wp-includes/css/dist/editor/editor-styles-rtl.css',
828
-	'wp-includes/css/dist/editor/editor-styles-rtl.min.css',
829
-	// 5.9
830
-	'wp-includes/blocks/heading/editor.css',
831
-	'wp-includes/blocks/heading/editor.min.css',
832
-	'wp-includes/blocks/heading/editor-rtl.css',
833
-	'wp-includes/blocks/heading/editor-rtl.min.css',
834
-	'wp-includes/blocks/post-content/editor.css',
835
-	'wp-includes/blocks/post-content/editor.min.css',
836
-	'wp-includes/blocks/post-content/editor-rtl.css',
837
-	'wp-includes/blocks/post-content/editor-rtl.min.css',
838
-	'wp-includes/blocks/query-title/editor.css',
839
-	'wp-includes/blocks/query-title/editor.min.css',
840
-	'wp-includes/blocks/query-title/editor-rtl.css',
841
-	'wp-includes/blocks/query-title/editor-rtl.min.css',
842
-	'wp-includes/blocks/tag-cloud/editor.css',
843
-	'wp-includes/blocks/tag-cloud/editor.min.css',
844
-	'wp-includes/blocks/tag-cloud/editor-rtl.css',
845
-	'wp-includes/blocks/tag-cloud/editor-rtl.min.css',
846
-	// 6.0
847
-	'wp-content/themes/twentytwentytwo/assets/fonts/LICENSE.md',
22
+    // 2.0
23
+    'wp-admin/import-b2.php',
24
+    'wp-admin/import-blogger.php',
25
+    'wp-admin/import-greymatter.php',
26
+    'wp-admin/import-livejournal.php',
27
+    'wp-admin/import-mt.php',
28
+    'wp-admin/import-rss.php',
29
+    'wp-admin/import-textpattern.php',
30
+    'wp-admin/quicktags.js',
31
+    'wp-images/fade-butt.png',
32
+    'wp-images/get-firefox.png',
33
+    'wp-images/header-shadow.png',
34
+    'wp-images/smilies',
35
+    'wp-images/wp-small.png',
36
+    'wp-images/wpminilogo.png',
37
+    'wp.php',
38
+    // 2.0.8
39
+    'wp-includes/js/tinymce/plugins/inlinepopups/readme.txt',
40
+    // 2.1
41
+    'wp-admin/edit-form-ajax-cat.php',
42
+    'wp-admin/execute-pings.php',
43
+    'wp-admin/inline-uploading.php',
44
+    'wp-admin/link-categories.php',
45
+    'wp-admin/list-manipulation.js',
46
+    'wp-admin/list-manipulation.php',
47
+    'wp-includes/comment-functions.php',
48
+    'wp-includes/feed-functions.php',
49
+    'wp-includes/functions-compat.php',
50
+    'wp-includes/functions-formatting.php',
51
+    'wp-includes/functions-post.php',
52
+    'wp-includes/js/dbx-key.js',
53
+    'wp-includes/js/tinymce/plugins/autosave/langs/cs.js',
54
+    'wp-includes/js/tinymce/plugins/autosave/langs/sv.js',
55
+    'wp-includes/links.php',
56
+    'wp-includes/pluggable-functions.php',
57
+    'wp-includes/template-functions-author.php',
58
+    'wp-includes/template-functions-category.php',
59
+    'wp-includes/template-functions-general.php',
60
+    'wp-includes/template-functions-links.php',
61
+    'wp-includes/template-functions-post.php',
62
+    'wp-includes/wp-l10n.php',
63
+    // 2.2
64
+    'wp-admin/cat-js.php',
65
+    'wp-admin/import/b2.php',
66
+    'wp-includes/js/autosave-js.php',
67
+    'wp-includes/js/list-manipulation-js.php',
68
+    'wp-includes/js/wp-ajax-js.php',
69
+    // 2.3
70
+    'wp-admin/admin-db.php',
71
+    'wp-admin/cat.js',
72
+    'wp-admin/categories.js',
73
+    'wp-admin/custom-fields.js',
74
+    'wp-admin/dbx-admin-key.js',
75
+    'wp-admin/edit-comments.js',
76
+    'wp-admin/install-rtl.css',
77
+    'wp-admin/install.css',
78
+    'wp-admin/upgrade-schema.php',
79
+    'wp-admin/upload-functions.php',
80
+    'wp-admin/upload-rtl.css',
81
+    'wp-admin/upload.css',
82
+    'wp-admin/upload.js',
83
+    'wp-admin/users.js',
84
+    'wp-admin/widgets-rtl.css',
85
+    'wp-admin/widgets.css',
86
+    'wp-admin/xfn.js',
87
+    'wp-includes/js/tinymce/license.html',
88
+    // 2.5
89
+    'wp-admin/css/upload.css',
90
+    'wp-admin/images/box-bg-left.gif',
91
+    'wp-admin/images/box-bg-right.gif',
92
+    'wp-admin/images/box-bg.gif',
93
+    'wp-admin/images/box-butt-left.gif',
94
+    'wp-admin/images/box-butt-right.gif',
95
+    'wp-admin/images/box-butt.gif',
96
+    'wp-admin/images/box-head-left.gif',
97
+    'wp-admin/images/box-head-right.gif',
98
+    'wp-admin/images/box-head.gif',
99
+    'wp-admin/images/heading-bg.gif',
100
+    'wp-admin/images/login-bkg-bottom.gif',
101
+    'wp-admin/images/login-bkg-tile.gif',
102
+    'wp-admin/images/notice.gif',
103
+    'wp-admin/images/toggle.gif',
104
+    'wp-admin/includes/upload.php',
105
+    'wp-admin/js/dbx-admin-key.js',
106
+    'wp-admin/js/link-cat.js',
107
+    'wp-admin/profile-update.php',
108
+    'wp-admin/templates.php',
109
+    'wp-includes/images/wlw/WpComments.png',
110
+    'wp-includes/images/wlw/WpIcon.png',
111
+    'wp-includes/images/wlw/WpWatermark.png',
112
+    'wp-includes/js/dbx.js',
113
+    'wp-includes/js/fat.js',
114
+    'wp-includes/js/list-manipulation.js',
115
+    'wp-includes/js/tinymce/langs/en.js',
116
+    'wp-includes/js/tinymce/plugins/autosave/editor_plugin_src.js',
117
+    'wp-includes/js/tinymce/plugins/autosave/langs',
118
+    'wp-includes/js/tinymce/plugins/directionality/images',
119
+    'wp-includes/js/tinymce/plugins/directionality/langs',
120
+    'wp-includes/js/tinymce/plugins/inlinepopups/css',
121
+    'wp-includes/js/tinymce/plugins/inlinepopups/images',
122
+    'wp-includes/js/tinymce/plugins/inlinepopups/jscripts',
123
+    'wp-includes/js/tinymce/plugins/paste/images',
124
+    'wp-includes/js/tinymce/plugins/paste/jscripts',
125
+    'wp-includes/js/tinymce/plugins/paste/langs',
126
+    'wp-includes/js/tinymce/plugins/spellchecker/classes/HttpClient.class.php',
127
+    'wp-includes/js/tinymce/plugins/spellchecker/classes/TinyGoogleSpell.class.php',
128
+    'wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspell.class.php',
129
+    'wp-includes/js/tinymce/plugins/spellchecker/classes/TinyPspellShell.class.php',
130
+    'wp-includes/js/tinymce/plugins/spellchecker/css/spellchecker.css',
131
+    'wp-includes/js/tinymce/plugins/spellchecker/images',
132
+    'wp-includes/js/tinymce/plugins/spellchecker/langs',
133
+    'wp-includes/js/tinymce/plugins/spellchecker/tinyspell.php',
134
+    'wp-includes/js/tinymce/plugins/wordpress/images',
135
+    'wp-includes/js/tinymce/plugins/wordpress/langs',
136
+    'wp-includes/js/tinymce/plugins/wordpress/wordpress.css',
137
+    'wp-includes/js/tinymce/plugins/wphelp',
138
+    'wp-includes/js/tinymce/themes/advanced/css',
139
+    'wp-includes/js/tinymce/themes/advanced/images',
140
+    'wp-includes/js/tinymce/themes/advanced/jscripts',
141
+    'wp-includes/js/tinymce/themes/advanced/langs',
142
+    // 2.5.1
143
+    'wp-includes/js/tinymce/tiny_mce_gzip.php',
144
+    // 2.6
145
+    'wp-admin/bookmarklet.php',
146
+    'wp-includes/js/jquery/jquery.dimensions.min.js',
147
+    'wp-includes/js/tinymce/plugins/wordpress/popups.css',
148
+    'wp-includes/js/wp-ajax.js',
149
+    // 2.7
150
+    'wp-admin/css/press-this-ie-rtl.css',
151
+    'wp-admin/css/press-this-ie.css',
152
+    'wp-admin/css/upload-rtl.css',
153
+    'wp-admin/edit-form.php',
154
+    'wp-admin/images/comment-pill.gif',
155
+    'wp-admin/images/comment-stalk-classic.gif',
156
+    'wp-admin/images/comment-stalk-fresh.gif',
157
+    'wp-admin/images/comment-stalk-rtl.gif',
158
+    'wp-admin/images/del.png',
159
+    'wp-admin/images/gear.png',
160
+    'wp-admin/images/media-button-gallery.gif',
161
+    'wp-admin/images/media-buttons.gif',
162
+    'wp-admin/images/postbox-bg.gif',
163
+    'wp-admin/images/tab.png',
164
+    'wp-admin/images/tail.gif',
165
+    'wp-admin/js/forms.js',
166
+    'wp-admin/js/upload.js',
167
+    'wp-admin/link-import.php',
168
+    'wp-includes/images/audio.png',
169
+    'wp-includes/images/css.png',
170
+    'wp-includes/images/default.png',
171
+    'wp-includes/images/doc.png',
172
+    'wp-includes/images/exe.png',
173
+    'wp-includes/images/html.png',
174
+    'wp-includes/images/js.png',
175
+    'wp-includes/images/pdf.png',
176
+    'wp-includes/images/swf.png',
177
+    'wp-includes/images/tar.png',
178
+    'wp-includes/images/text.png',
179
+    'wp-includes/images/video.png',
180
+    'wp-includes/images/zip.png',
181
+    'wp-includes/js/tinymce/tiny_mce_config.php',
182
+    'wp-includes/js/tinymce/tiny_mce_ext.js',
183
+    // 2.8
184
+    'wp-admin/js/users.js',
185
+    'wp-includes/js/swfupload/plugins/swfupload.documentready.js',
186
+    'wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js',
187
+    'wp-includes/js/swfupload/swfupload_f9.swf',
188
+    'wp-includes/js/tinymce/plugins/autosave',
189
+    'wp-includes/js/tinymce/plugins/paste/css',
190
+    'wp-includes/js/tinymce/utils/mclayer.js',
191
+    'wp-includes/js/tinymce/wordpress.css',
192
+    // 2.8.5
193
+    'wp-admin/import/btt.php',
194
+    'wp-admin/import/jkw.php',
195
+    // 2.9
196
+    'wp-admin/js/page.dev.js',
197
+    'wp-admin/js/page.js',
198
+    'wp-admin/js/set-post-thumbnail-handler.dev.js',
199
+    'wp-admin/js/set-post-thumbnail-handler.js',
200
+    'wp-admin/js/slug.dev.js',
201
+    'wp-admin/js/slug.js',
202
+    'wp-includes/gettext.php',
203
+    'wp-includes/js/tinymce/plugins/wordpress/js',
204
+    'wp-includes/streams.php',
205
+    // MU
206
+    'README.txt',
207
+    'htaccess.dist',
208
+    'index-install.php',
209
+    'wp-admin/css/mu-rtl.css',
210
+    'wp-admin/css/mu.css',
211
+    'wp-admin/images/site-admin.png',
212
+    'wp-admin/includes/mu.php',
213
+    'wp-admin/wpmu-admin.php',
214
+    'wp-admin/wpmu-blogs.php',
215
+    'wp-admin/wpmu-edit.php',
216
+    'wp-admin/wpmu-options.php',
217
+    'wp-admin/wpmu-themes.php',
218
+    'wp-admin/wpmu-upgrade-site.php',
219
+    'wp-admin/wpmu-users.php',
220
+    'wp-includes/images/wordpress-mu.png',
221
+    'wp-includes/wpmu-default-filters.php',
222
+    'wp-includes/wpmu-functions.php',
223
+    'wpmu-settings.php',
224
+    // 3.0
225
+    'wp-admin/categories.php',
226
+    'wp-admin/edit-category-form.php',
227
+    'wp-admin/edit-page-form.php',
228
+    'wp-admin/edit-pages.php',
229
+    'wp-admin/images/admin-header-footer.png',
230
+    'wp-admin/images/browse-happy.gif',
231
+    'wp-admin/images/ico-add.png',
232
+    'wp-admin/images/ico-close.png',
233
+    'wp-admin/images/ico-edit.png',
234
+    'wp-admin/images/ico-viewpage.png',
235
+    'wp-admin/images/fav-top.png',
236
+    'wp-admin/images/screen-options-left.gif',
237
+    'wp-admin/images/wp-logo-vs.gif',
238
+    'wp-admin/images/wp-logo.gif',
239
+    'wp-admin/import',
240
+    'wp-admin/js/wp-gears.dev.js',
241
+    'wp-admin/js/wp-gears.js',
242
+    'wp-admin/options-misc.php',
243
+    'wp-admin/page-new.php',
244
+    'wp-admin/page.php',
245
+    'wp-admin/rtl.css',
246
+    'wp-admin/rtl.dev.css',
247
+    'wp-admin/update-links.php',
248
+    'wp-admin/wp-admin.css',
249
+    'wp-admin/wp-admin.dev.css',
250
+    'wp-includes/js/codepress',
251
+    'wp-includes/js/codepress/engines/khtml.js',
252
+    'wp-includes/js/codepress/engines/older.js',
253
+    'wp-includes/js/jquery/autocomplete.dev.js',
254
+    'wp-includes/js/jquery/autocomplete.js',
255
+    'wp-includes/js/jquery/interface.js',
256
+    'wp-includes/js/scriptaculous/prototype.js',
257
+    // Following file added back in 5.1, see #45645.
258
+    //'wp-includes/js/tinymce/wp-tinymce.js',
259
+    // 3.1
260
+    'wp-admin/edit-attachment-rows.php',
261
+    'wp-admin/edit-link-categories.php',
262
+    'wp-admin/edit-link-category-form.php',
263
+    'wp-admin/edit-post-rows.php',
264
+    'wp-admin/images/button-grad-active-vs.png',
265
+    'wp-admin/images/button-grad-vs.png',
266
+    'wp-admin/images/fav-arrow-vs-rtl.gif',
267
+    'wp-admin/images/fav-arrow-vs.gif',
268
+    'wp-admin/images/fav-top-vs.gif',
269
+    'wp-admin/images/list-vs.png',
270
+    'wp-admin/images/screen-options-right-up.gif',
271
+    'wp-admin/images/screen-options-right.gif',
272
+    'wp-admin/images/visit-site-button-grad-vs.gif',
273
+    'wp-admin/images/visit-site-button-grad.gif',
274
+    'wp-admin/link-category.php',
275
+    'wp-admin/sidebar.php',
276
+    'wp-includes/classes.php',
277
+    'wp-includes/js/tinymce/blank.htm',
278
+    'wp-includes/js/tinymce/plugins/media/css/content.css',
279
+    'wp-includes/js/tinymce/plugins/media/img',
280
+    'wp-includes/js/tinymce/plugins/safari',
281
+    // 3.2
282
+    'wp-admin/images/logo-login.gif',
283
+    'wp-admin/images/star.gif',
284
+    'wp-admin/js/list-table.dev.js',
285
+    'wp-admin/js/list-table.js',
286
+    'wp-includes/default-embeds.php',
287
+    'wp-includes/js/tinymce/plugins/wordpress/img/help.gif',
288
+    'wp-includes/js/tinymce/plugins/wordpress/img/more.gif',
289
+    'wp-includes/js/tinymce/plugins/wordpress/img/toolbars.gif',
290
+    'wp-includes/js/tinymce/themes/advanced/img/fm.gif',
291
+    'wp-includes/js/tinymce/themes/advanced/img/sflogo.png',
292
+    // 3.3
293
+    'wp-admin/css/colors-classic-rtl.css',
294
+    'wp-admin/css/colors-classic-rtl.dev.css',
295
+    'wp-admin/css/colors-fresh-rtl.css',
296
+    'wp-admin/css/colors-fresh-rtl.dev.css',
297
+    'wp-admin/css/dashboard-rtl.dev.css',
298
+    'wp-admin/css/dashboard.dev.css',
299
+    'wp-admin/css/global-rtl.css',
300
+    'wp-admin/css/global-rtl.dev.css',
301
+    'wp-admin/css/global.css',
302
+    'wp-admin/css/global.dev.css',
303
+    'wp-admin/css/install-rtl.dev.css',
304
+    'wp-admin/css/login-rtl.dev.css',
305
+    'wp-admin/css/login.dev.css',
306
+    'wp-admin/css/ms.css',
307
+    'wp-admin/css/ms.dev.css',
308
+    'wp-admin/css/nav-menu-rtl.css',
309
+    'wp-admin/css/nav-menu-rtl.dev.css',
310
+    'wp-admin/css/nav-menu.css',
311
+    'wp-admin/css/nav-menu.dev.css',
312
+    'wp-admin/css/plugin-install-rtl.css',
313
+    'wp-admin/css/plugin-install-rtl.dev.css',
314
+    'wp-admin/css/plugin-install.css',
315
+    'wp-admin/css/plugin-install.dev.css',
316
+    'wp-admin/css/press-this-rtl.dev.css',
317
+    'wp-admin/css/press-this.dev.css',
318
+    'wp-admin/css/theme-editor-rtl.css',
319
+    'wp-admin/css/theme-editor-rtl.dev.css',
320
+    'wp-admin/css/theme-editor.css',
321
+    'wp-admin/css/theme-editor.dev.css',
322
+    'wp-admin/css/theme-install-rtl.css',
323
+    'wp-admin/css/theme-install-rtl.dev.css',
324
+    'wp-admin/css/theme-install.css',
325
+    'wp-admin/css/theme-install.dev.css',
326
+    'wp-admin/css/widgets-rtl.dev.css',
327
+    'wp-admin/css/widgets.dev.css',
328
+    'wp-admin/includes/internal-linking.php',
329
+    'wp-includes/images/admin-bar-sprite-rtl.png',
330
+    'wp-includes/js/jquery/ui.button.js',
331
+    'wp-includes/js/jquery/ui.core.js',
332
+    'wp-includes/js/jquery/ui.dialog.js',
333
+    'wp-includes/js/jquery/ui.draggable.js',
334
+    'wp-includes/js/jquery/ui.droppable.js',
335
+    'wp-includes/js/jquery/ui.mouse.js',
336
+    'wp-includes/js/jquery/ui.position.js',
337
+    'wp-includes/js/jquery/ui.resizable.js',
338
+    'wp-includes/js/jquery/ui.selectable.js',
339
+    'wp-includes/js/jquery/ui.sortable.js',
340
+    'wp-includes/js/jquery/ui.tabs.js',
341
+    'wp-includes/js/jquery/ui.widget.js',
342
+    'wp-includes/js/l10n.dev.js',
343
+    'wp-includes/js/l10n.js',
344
+    'wp-includes/js/tinymce/plugins/wplink/css',
345
+    'wp-includes/js/tinymce/plugins/wplink/img',
346
+    'wp-includes/js/tinymce/plugins/wplink/js',
347
+    'wp-includes/js/tinymce/themes/advanced/img/wpicons.png',
348
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/butt2.png',
349
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/button_bg.png',
350
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/down_arrow.gif',
351
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/fade-butt.png',
352
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/separator.gif',
353
+    // Don't delete, yet: 'wp-rss.php',
354
+    // Don't delete, yet: 'wp-rdf.php',
355
+    // Don't delete, yet: 'wp-rss2.php',
356
+    // Don't delete, yet: 'wp-commentsrss2.php',
357
+    // Don't delete, yet: 'wp-atom.php',
358
+    // Don't delete, yet: 'wp-feed.php',
359
+    // 3.4
360
+    'wp-admin/images/gray-star.png',
361
+    'wp-admin/images/logo-login.png',
362
+    'wp-admin/images/star.png',
363
+    'wp-admin/index-extra.php',
364
+    'wp-admin/network/index-extra.php',
365
+    'wp-admin/user/index-extra.php',
366
+    'wp-admin/images/screenshots/admin-flyouts.png',
367
+    'wp-admin/images/screenshots/coediting.png',
368
+    'wp-admin/images/screenshots/drag-and-drop.png',
369
+    'wp-admin/images/screenshots/help-screen.png',
370
+    'wp-admin/images/screenshots/media-icon.png',
371
+    'wp-admin/images/screenshots/new-feature-pointer.png',
372
+    'wp-admin/images/screenshots/welcome-screen.png',
373
+    'wp-includes/css/editor-buttons.css',
374
+    'wp-includes/css/editor-buttons.dev.css',
375
+    'wp-includes/js/tinymce/plugins/paste/blank.htm',
376
+    'wp-includes/js/tinymce/plugins/wordpress/css',
377
+    'wp-includes/js/tinymce/plugins/wordpress/editor_plugin.dev.js',
378
+    'wp-includes/js/tinymce/plugins/wordpress/img/embedded.png',
379
+    'wp-includes/js/tinymce/plugins/wordpress/img/more_bug.gif',
380
+    'wp-includes/js/tinymce/plugins/wordpress/img/page_bug.gif',
381
+    'wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.dev.js',
382
+    'wp-includes/js/tinymce/plugins/wpeditimage/css/editimage-rtl.css',
383
+    'wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.dev.js',
384
+    'wp-includes/js/tinymce/plugins/wpfullscreen/editor_plugin.dev.js',
385
+    'wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.dev.js',
386
+    'wp-includes/js/tinymce/plugins/wpgallery/img/gallery.png',
387
+    'wp-includes/js/tinymce/plugins/wplink/editor_plugin.dev.js',
388
+    // Don't delete, yet: 'wp-pass.php',
389
+    // Don't delete, yet: 'wp-register.php',
390
+    // 3.5
391
+    'wp-admin/gears-manifest.php',
392
+    'wp-admin/includes/manifest.php',
393
+    'wp-admin/images/archive-link.png',
394
+    'wp-admin/images/blue-grad.png',
395
+    'wp-admin/images/button-grad-active.png',
396
+    'wp-admin/images/button-grad.png',
397
+    'wp-admin/images/ed-bg-vs.gif',
398
+    'wp-admin/images/ed-bg.gif',
399
+    'wp-admin/images/fade-butt.png',
400
+    'wp-admin/images/fav-arrow-rtl.gif',
401
+    'wp-admin/images/fav-arrow.gif',
402
+    'wp-admin/images/fav-vs.png',
403
+    'wp-admin/images/fav.png',
404
+    'wp-admin/images/gray-grad.png',
405
+    'wp-admin/images/loading-publish.gif',
406
+    'wp-admin/images/logo-ghost.png',
407
+    'wp-admin/images/logo.gif',
408
+    'wp-admin/images/menu-arrow-frame-rtl.png',
409
+    'wp-admin/images/menu-arrow-frame.png',
410
+    'wp-admin/images/menu-arrows.gif',
411
+    'wp-admin/images/menu-bits-rtl-vs.gif',
412
+    'wp-admin/images/menu-bits-rtl.gif',
413
+    'wp-admin/images/menu-bits-vs.gif',
414
+    'wp-admin/images/menu-bits.gif',
415
+    'wp-admin/images/menu-dark-rtl-vs.gif',
416
+    'wp-admin/images/menu-dark-rtl.gif',
417
+    'wp-admin/images/menu-dark-vs.gif',
418
+    'wp-admin/images/menu-dark.gif',
419
+    'wp-admin/images/required.gif',
420
+    'wp-admin/images/screen-options-toggle-vs.gif',
421
+    'wp-admin/images/screen-options-toggle.gif',
422
+    'wp-admin/images/toggle-arrow-rtl.gif',
423
+    'wp-admin/images/toggle-arrow.gif',
424
+    'wp-admin/images/upload-classic.png',
425
+    'wp-admin/images/upload-fresh.png',
426
+    'wp-admin/images/white-grad-active.png',
427
+    'wp-admin/images/white-grad.png',
428
+    'wp-admin/images/widgets-arrow-vs.gif',
429
+    'wp-admin/images/widgets-arrow.gif',
430
+    'wp-admin/images/wpspin_dark.gif',
431
+    'wp-includes/images/upload.png',
432
+    'wp-includes/js/prototype.js',
433
+    'wp-includes/js/scriptaculous',
434
+    'wp-admin/css/wp-admin-rtl.dev.css',
435
+    'wp-admin/css/wp-admin.dev.css',
436
+    'wp-admin/css/media-rtl.dev.css',
437
+    'wp-admin/css/media.dev.css',
438
+    'wp-admin/css/colors-classic.dev.css',
439
+    'wp-admin/css/customize-controls-rtl.dev.css',
440
+    'wp-admin/css/customize-controls.dev.css',
441
+    'wp-admin/css/ie-rtl.dev.css',
442
+    'wp-admin/css/ie.dev.css',
443
+    'wp-admin/css/install.dev.css',
444
+    'wp-admin/css/colors-fresh.dev.css',
445
+    'wp-includes/js/customize-base.dev.js',
446
+    'wp-includes/js/json2.dev.js',
447
+    'wp-includes/js/comment-reply.dev.js',
448
+    'wp-includes/js/customize-preview.dev.js',
449
+    'wp-includes/js/wplink.dev.js',
450
+    'wp-includes/js/tw-sack.dev.js',
451
+    'wp-includes/js/wp-list-revisions.dev.js',
452
+    'wp-includes/js/autosave.dev.js',
453
+    'wp-includes/js/admin-bar.dev.js',
454
+    'wp-includes/js/quicktags.dev.js',
455
+    'wp-includes/js/wp-ajax-response.dev.js',
456
+    'wp-includes/js/wp-pointer.dev.js',
457
+    'wp-includes/js/hoverIntent.dev.js',
458
+    'wp-includes/js/colorpicker.dev.js',
459
+    'wp-includes/js/wp-lists.dev.js',
460
+    'wp-includes/js/customize-loader.dev.js',
461
+    'wp-includes/js/jquery/jquery.table-hotkeys.dev.js',
462
+    'wp-includes/js/jquery/jquery.color.dev.js',
463
+    'wp-includes/js/jquery/jquery.color.js',
464
+    'wp-includes/js/jquery/jquery.hotkeys.dev.js',
465
+    'wp-includes/js/jquery/jquery.form.dev.js',
466
+    'wp-includes/js/jquery/suggest.dev.js',
467
+    'wp-admin/js/xfn.dev.js',
468
+    'wp-admin/js/set-post-thumbnail.dev.js',
469
+    'wp-admin/js/comment.dev.js',
470
+    'wp-admin/js/theme.dev.js',
471
+    'wp-admin/js/cat.dev.js',
472
+    'wp-admin/js/password-strength-meter.dev.js',
473
+    'wp-admin/js/user-profile.dev.js',
474
+    'wp-admin/js/theme-preview.dev.js',
475
+    'wp-admin/js/post.dev.js',
476
+    'wp-admin/js/media-upload.dev.js',
477
+    'wp-admin/js/word-count.dev.js',
478
+    'wp-admin/js/plugin-install.dev.js',
479
+    'wp-admin/js/edit-comments.dev.js',
480
+    'wp-admin/js/media-gallery.dev.js',
481
+    'wp-admin/js/custom-fields.dev.js',
482
+    'wp-admin/js/custom-background.dev.js',
483
+    'wp-admin/js/common.dev.js',
484
+    'wp-admin/js/inline-edit-tax.dev.js',
485
+    'wp-admin/js/gallery.dev.js',
486
+    'wp-admin/js/utils.dev.js',
487
+    'wp-admin/js/widgets.dev.js',
488
+    'wp-admin/js/wp-fullscreen.dev.js',
489
+    'wp-admin/js/nav-menu.dev.js',
490
+    'wp-admin/js/dashboard.dev.js',
491
+    'wp-admin/js/link.dev.js',
492
+    'wp-admin/js/user-suggest.dev.js',
493
+    'wp-admin/js/postbox.dev.js',
494
+    'wp-admin/js/tags.dev.js',
495
+    'wp-admin/js/image-edit.dev.js',
496
+    'wp-admin/js/media.dev.js',
497
+    'wp-admin/js/customize-controls.dev.js',
498
+    'wp-admin/js/inline-edit-post.dev.js',
499
+    'wp-admin/js/categories.dev.js',
500
+    'wp-admin/js/editor.dev.js',
501
+    'wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js',
502
+    'wp-includes/js/tinymce/plugins/wpdialogs/js/popup.dev.js',
503
+    'wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.dev.js',
504
+    'wp-includes/js/plupload/handlers.dev.js',
505
+    'wp-includes/js/plupload/wp-plupload.dev.js',
506
+    'wp-includes/js/swfupload/handlers.dev.js',
507
+    'wp-includes/js/jcrop/jquery.Jcrop.dev.js',
508
+    'wp-includes/js/jcrop/jquery.Jcrop.js',
509
+    'wp-includes/js/jcrop/jquery.Jcrop.css',
510
+    'wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js',
511
+    'wp-includes/css/wp-pointer.dev.css',
512
+    'wp-includes/css/editor.dev.css',
513
+    'wp-includes/css/jquery-ui-dialog.dev.css',
514
+    'wp-includes/css/admin-bar-rtl.dev.css',
515
+    'wp-includes/css/admin-bar.dev.css',
516
+    'wp-includes/js/jquery/ui/jquery.effects.clip.min.js',
517
+    'wp-includes/js/jquery/ui/jquery.effects.scale.min.js',
518
+    'wp-includes/js/jquery/ui/jquery.effects.blind.min.js',
519
+    'wp-includes/js/jquery/ui/jquery.effects.core.min.js',
520
+    'wp-includes/js/jquery/ui/jquery.effects.shake.min.js',
521
+    'wp-includes/js/jquery/ui/jquery.effects.fade.min.js',
522
+    'wp-includes/js/jquery/ui/jquery.effects.explode.min.js',
523
+    'wp-includes/js/jquery/ui/jquery.effects.slide.min.js',
524
+    'wp-includes/js/jquery/ui/jquery.effects.drop.min.js',
525
+    'wp-includes/js/jquery/ui/jquery.effects.highlight.min.js',
526
+    'wp-includes/js/jquery/ui/jquery.effects.bounce.min.js',
527
+    'wp-includes/js/jquery/ui/jquery.effects.pulsate.min.js',
528
+    'wp-includes/js/jquery/ui/jquery.effects.transfer.min.js',
529
+    'wp-includes/js/jquery/ui/jquery.effects.fold.min.js',
530
+    'wp-admin/images/screenshots/captions-1.png',
531
+    'wp-admin/images/screenshots/captions-2.png',
532
+    'wp-admin/images/screenshots/flex-header-1.png',
533
+    'wp-admin/images/screenshots/flex-header-2.png',
534
+    'wp-admin/images/screenshots/flex-header-3.png',
535
+    'wp-admin/images/screenshots/flex-header-media-library.png',
536
+    'wp-admin/images/screenshots/theme-customizer.png',
537
+    'wp-admin/images/screenshots/twitter-embed-1.png',
538
+    'wp-admin/images/screenshots/twitter-embed-2.png',
539
+    'wp-admin/js/utils.js',
540
+    // Added back in 5.3 [45448], see #43895.
541
+    // 'wp-admin/options-privacy.php',
542
+    'wp-app.php',
543
+    'wp-includes/class-wp-atom-server.php',
544
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/ui.css',
545
+    // 3.5.2
546
+    'wp-includes/js/swfupload/swfupload-all.js',
547
+    // 3.6
548
+    'wp-admin/js/revisions-js.php',
549
+    'wp-admin/images/screenshots',
550
+    'wp-admin/js/categories.js',
551
+    'wp-admin/js/categories.min.js',
552
+    'wp-admin/js/custom-fields.js',
553
+    'wp-admin/js/custom-fields.min.js',
554
+    // 3.7
555
+    'wp-admin/js/cat.js',
556
+    'wp-admin/js/cat.min.js',
557
+    'wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.min.js',
558
+    // 3.8
559
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/page_bug.gif',
560
+    'wp-includes/js/tinymce/themes/advanced/skins/wp_theme/img/more_bug.gif',
561
+    'wp-includes/js/thickbox/tb-close-2x.png',
562
+    'wp-includes/js/thickbox/tb-close.png',
563
+    'wp-includes/images/wpmini-blue-2x.png',
564
+    'wp-includes/images/wpmini-blue.png',
565
+    'wp-admin/css/colors-fresh.css',
566
+    'wp-admin/css/colors-classic.css',
567
+    'wp-admin/css/colors-fresh.min.css',
568
+    'wp-admin/css/colors-classic.min.css',
569
+    'wp-admin/js/about.min.js',
570
+    'wp-admin/js/about.js',
571
+    'wp-admin/images/arrows-dark-vs-2x.png',
572
+    'wp-admin/images/wp-logo-vs.png',
573
+    'wp-admin/images/arrows-dark-vs.png',
574
+    'wp-admin/images/wp-logo.png',
575
+    'wp-admin/images/arrows-pr.png',
576
+    'wp-admin/images/arrows-dark.png',
577
+    'wp-admin/images/press-this.png',
578
+    'wp-admin/images/press-this-2x.png',
579
+    'wp-admin/images/arrows-vs-2x.png',
580
+    'wp-admin/images/welcome-icons.png',
581
+    'wp-admin/images/wp-logo-2x.png',
582
+    'wp-admin/images/stars-rtl-2x.png',
583
+    'wp-admin/images/arrows-dark-2x.png',
584
+    'wp-admin/images/arrows-pr-2x.png',
585
+    'wp-admin/images/menu-shadow-rtl.png',
586
+    'wp-admin/images/arrows-vs.png',
587
+    'wp-admin/images/about-search-2x.png',
588
+    'wp-admin/images/bubble_bg-rtl-2x.gif',
589
+    'wp-admin/images/wp-badge-2x.png',
590
+    'wp-admin/images/wordpress-logo-2x.png',
591
+    'wp-admin/images/bubble_bg-rtl.gif',
592
+    'wp-admin/images/wp-badge.png',
593
+    'wp-admin/images/menu-shadow.png',
594
+    'wp-admin/images/about-globe-2x.png',
595
+    'wp-admin/images/welcome-icons-2x.png',
596
+    'wp-admin/images/stars-rtl.png',
597
+    'wp-admin/images/wp-logo-vs-2x.png',
598
+    'wp-admin/images/about-updates-2x.png',
599
+    // 3.9
600
+    'wp-admin/css/colors.css',
601
+    'wp-admin/css/colors.min.css',
602
+    'wp-admin/css/colors-rtl.css',
603
+    'wp-admin/css/colors-rtl.min.css',
604
+    // Following files added back in 4.5, see #36083.
605
+    // 'wp-admin/css/media-rtl.min.css',
606
+    // 'wp-admin/css/media.min.css',
607
+    // 'wp-admin/css/farbtastic-rtl.min.css',
608
+    'wp-admin/images/lock-2x.png',
609
+    'wp-admin/images/lock.png',
610
+    'wp-admin/js/theme-preview.js',
611
+    'wp-admin/js/theme-install.min.js',
612
+    'wp-admin/js/theme-install.js',
613
+    'wp-admin/js/theme-preview.min.js',
614
+    'wp-includes/js/plupload/plupload.html4.js',
615
+    'wp-includes/js/plupload/plupload.html5.js',
616
+    'wp-includes/js/plupload/changelog.txt',
617
+    'wp-includes/js/plupload/plupload.silverlight.js',
618
+    'wp-includes/js/plupload/plupload.flash.js',
619
+    // Added back in 4.9 [41328], see #41755.
620
+    // 'wp-includes/js/plupload/plupload.js',
621
+    'wp-includes/js/tinymce/plugins/spellchecker',
622
+    'wp-includes/js/tinymce/plugins/inlinepopups',
623
+    'wp-includes/js/tinymce/plugins/media/js',
624
+    'wp-includes/js/tinymce/plugins/media/css',
625
+    'wp-includes/js/tinymce/plugins/wordpress/img',
626
+    'wp-includes/js/tinymce/plugins/wpdialogs/js',
627
+    'wp-includes/js/tinymce/plugins/wpeditimage/img',
628
+    'wp-includes/js/tinymce/plugins/wpeditimage/js',
629
+    'wp-includes/js/tinymce/plugins/wpeditimage/css',
630
+    'wp-includes/js/tinymce/plugins/wpgallery/img',
631
+    'wp-includes/js/tinymce/plugins/wpfullscreen/css',
632
+    'wp-includes/js/tinymce/plugins/paste/js',
633
+    'wp-includes/js/tinymce/themes/advanced',
634
+    'wp-includes/js/tinymce/tiny_mce.js',
635
+    'wp-includes/js/tinymce/mark_loaded_src.js',
636
+    'wp-includes/js/tinymce/wp-tinymce-schema.js',
637
+    'wp-includes/js/tinymce/plugins/media/editor_plugin.js',
638
+    'wp-includes/js/tinymce/plugins/media/editor_plugin_src.js',
639
+    'wp-includes/js/tinymce/plugins/media/media.htm',
640
+    'wp-includes/js/tinymce/plugins/wpview/editor_plugin_src.js',
641
+    'wp-includes/js/tinymce/plugins/wpview/editor_plugin.js',
642
+    'wp-includes/js/tinymce/plugins/directionality/editor_plugin.js',
643
+    'wp-includes/js/tinymce/plugins/directionality/editor_plugin_src.js',
644
+    'wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js',
645
+    'wp-includes/js/tinymce/plugins/wordpress/editor_plugin_src.js',
646
+    'wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin_src.js',
647
+    'wp-includes/js/tinymce/plugins/wpdialogs/editor_plugin.js',
648
+    'wp-includes/js/tinymce/plugins/wpeditimage/editimage.html',
649
+    'wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin.js',
650
+    'wp-includes/js/tinymce/plugins/wpeditimage/editor_plugin_src.js',
651
+    'wp-includes/js/tinymce/plugins/fullscreen/editor_plugin_src.js',
652
+    'wp-includes/js/tinymce/plugins/fullscreen/fullscreen.htm',
653
+    'wp-includes/js/tinymce/plugins/fullscreen/editor_plugin.js',
654
+    'wp-includes/js/tinymce/plugins/wplink/editor_plugin_src.js',
655
+    'wp-includes/js/tinymce/plugins/wplink/editor_plugin.js',
656
+    'wp-includes/js/tinymce/plugins/wpgallery/editor_plugin_src.js',
657
+    'wp-includes/js/tinymce/plugins/wpgallery/editor_plugin.js',
658
+    'wp-includes/js/tinymce/plugins/tabfocus/editor_plugin.js',
659
+    'wp-includes/js/tinymce/plugins/tabfocus/editor_plugin_src.js',
660
+    'wp-includes/js/tinymce/plugins/wpfullscreen/editor_plugin.js',
661
+    'wp-includes/js/tinymce/plugins/wpfullscreen/editor_plugin_src.js',
662
+    'wp-includes/js/tinymce/plugins/paste/editor_plugin.js',
663
+    'wp-includes/js/tinymce/plugins/paste/pasteword.htm',
664
+    'wp-includes/js/tinymce/plugins/paste/editor_plugin_src.js',
665
+    'wp-includes/js/tinymce/plugins/paste/pastetext.htm',
666
+    'wp-includes/js/tinymce/langs/wp-langs.php',
667
+    // 4.1
668
+    'wp-includes/js/jquery/ui/jquery.ui.accordion.min.js',
669
+    'wp-includes/js/jquery/ui/jquery.ui.autocomplete.min.js',
670
+    'wp-includes/js/jquery/ui/jquery.ui.button.min.js',
671
+    'wp-includes/js/jquery/ui/jquery.ui.core.min.js',
672
+    'wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js',
673
+    'wp-includes/js/jquery/ui/jquery.ui.dialog.min.js',
674
+    'wp-includes/js/jquery/ui/jquery.ui.draggable.min.js',
675
+    'wp-includes/js/jquery/ui/jquery.ui.droppable.min.js',
676
+    'wp-includes/js/jquery/ui/jquery.ui.effect-blind.min.js',
677
+    'wp-includes/js/jquery/ui/jquery.ui.effect-bounce.min.js',
678
+    'wp-includes/js/jquery/ui/jquery.ui.effect-clip.min.js',
679
+    'wp-includes/js/jquery/ui/jquery.ui.effect-drop.min.js',
680
+    'wp-includes/js/jquery/ui/jquery.ui.effect-explode.min.js',
681
+    'wp-includes/js/jquery/ui/jquery.ui.effect-fade.min.js',
682
+    'wp-includes/js/jquery/ui/jquery.ui.effect-fold.min.js',
683
+    'wp-includes/js/jquery/ui/jquery.ui.effect-highlight.min.js',
684
+    'wp-includes/js/jquery/ui/jquery.ui.effect-pulsate.min.js',
685
+    'wp-includes/js/jquery/ui/jquery.ui.effect-scale.min.js',
686
+    'wp-includes/js/jquery/ui/jquery.ui.effect-shake.min.js',
687
+    'wp-includes/js/jquery/ui/jquery.ui.effect-slide.min.js',
688
+    'wp-includes/js/jquery/ui/jquery.ui.effect-transfer.min.js',
689
+    'wp-includes/js/jquery/ui/jquery.ui.effect.min.js',
690
+    'wp-includes/js/jquery/ui/jquery.ui.menu.min.js',
691
+    'wp-includes/js/jquery/ui/jquery.ui.mouse.min.js',
692
+    'wp-includes/js/jquery/ui/jquery.ui.position.min.js',
693
+    'wp-includes/js/jquery/ui/jquery.ui.progressbar.min.js',
694
+    'wp-includes/js/jquery/ui/jquery.ui.resizable.min.js',
695
+    'wp-includes/js/jquery/ui/jquery.ui.selectable.min.js',
696
+    'wp-includes/js/jquery/ui/jquery.ui.slider.min.js',
697
+    'wp-includes/js/jquery/ui/jquery.ui.sortable.min.js',
698
+    'wp-includes/js/jquery/ui/jquery.ui.spinner.min.js',
699
+    'wp-includes/js/jquery/ui/jquery.ui.tabs.min.js',
700
+    'wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js',
701
+    'wp-includes/js/jquery/ui/jquery.ui.widget.min.js',
702
+    'wp-includes/js/tinymce/skins/wordpress/images/dashicon-no-alt.png',
703
+    // 4.3
704
+    'wp-admin/js/wp-fullscreen.js',
705
+    'wp-admin/js/wp-fullscreen.min.js',
706
+    'wp-includes/js/tinymce/wp-mce-help.php',
707
+    'wp-includes/js/tinymce/plugins/wpfullscreen',
708
+    // 4.5
709
+    'wp-includes/theme-compat/comments-popup.php',
710
+    // 4.6
711
+    'wp-admin/includes/class-wp-automatic-upgrader.php', // Wrong file name, see #37628.
712
+    // 4.8
713
+    'wp-includes/js/tinymce/plugins/wpembed',
714
+    'wp-includes/js/tinymce/plugins/media/moxieplayer.swf',
715
+    'wp-includes/js/tinymce/skins/lightgray/fonts/readme.md',
716
+    'wp-includes/js/tinymce/skins/lightgray/fonts/tinymce-small.json',
717
+    'wp-includes/js/tinymce/skins/lightgray/fonts/tinymce.json',
718
+    'wp-includes/js/tinymce/skins/lightgray/skin.ie7.min.css',
719
+    // 4.9
720
+    'wp-admin/css/press-this-editor-rtl.css',
721
+    'wp-admin/css/press-this-editor-rtl.min.css',
722
+    'wp-admin/css/press-this-editor.css',
723
+    'wp-admin/css/press-this-editor.min.css',
724
+    'wp-admin/css/press-this-rtl.css',
725
+    'wp-admin/css/press-this-rtl.min.css',
726
+    'wp-admin/css/press-this.css',
727
+    'wp-admin/css/press-this.min.css',
728
+    'wp-admin/includes/class-wp-press-this.php',
729
+    'wp-admin/js/bookmarklet.js',
730
+    'wp-admin/js/bookmarklet.min.js',
731
+    'wp-admin/js/press-this.js',
732
+    'wp-admin/js/press-this.min.js',
733
+    'wp-includes/js/mediaelement/background.png',
734
+    'wp-includes/js/mediaelement/bigplay.png',
735
+    'wp-includes/js/mediaelement/bigplay.svg',
736
+    'wp-includes/js/mediaelement/controls.png',
737
+    'wp-includes/js/mediaelement/controls.svg',
738
+    'wp-includes/js/mediaelement/flashmediaelement.swf',
739
+    'wp-includes/js/mediaelement/froogaloop.min.js',
740
+    'wp-includes/js/mediaelement/jumpforward.png',
741
+    'wp-includes/js/mediaelement/loading.gif',
742
+    'wp-includes/js/mediaelement/silverlightmediaelement.xap',
743
+    'wp-includes/js/mediaelement/skipback.png',
744
+    'wp-includes/js/plupload/plupload.flash.swf',
745
+    'wp-includes/js/plupload/plupload.full.min.js',
746
+    'wp-includes/js/plupload/plupload.silverlight.xap',
747
+    'wp-includes/js/swfupload/plugins',
748
+    'wp-includes/js/swfupload/swfupload.swf',
749
+    // 4.9.2
750
+    'wp-includes/js/mediaelement/lang',
751
+    'wp-includes/js/mediaelement/lang/ca.js',
752
+    'wp-includes/js/mediaelement/lang/cs.js',
753
+    'wp-includes/js/mediaelement/lang/de.js',
754
+    'wp-includes/js/mediaelement/lang/es.js',
755
+    'wp-includes/js/mediaelement/lang/fa.js',
756
+    'wp-includes/js/mediaelement/lang/fr.js',
757
+    'wp-includes/js/mediaelement/lang/hr.js',
758
+    'wp-includes/js/mediaelement/lang/hu.js',
759
+    'wp-includes/js/mediaelement/lang/it.js',
760
+    'wp-includes/js/mediaelement/lang/ja.js',
761
+    'wp-includes/js/mediaelement/lang/ko.js',
762
+    'wp-includes/js/mediaelement/lang/nl.js',
763
+    'wp-includes/js/mediaelement/lang/pl.js',
764
+    'wp-includes/js/mediaelement/lang/pt.js',
765
+    'wp-includes/js/mediaelement/lang/ro.js',
766
+    'wp-includes/js/mediaelement/lang/ru.js',
767
+    'wp-includes/js/mediaelement/lang/sk.js',
768
+    'wp-includes/js/mediaelement/lang/sv.js',
769
+    'wp-includes/js/mediaelement/lang/uk.js',
770
+    'wp-includes/js/mediaelement/lang/zh-cn.js',
771
+    'wp-includes/js/mediaelement/lang/zh.js',
772
+    'wp-includes/js/mediaelement/mediaelement-flash-audio-ogg.swf',
773
+    'wp-includes/js/mediaelement/mediaelement-flash-audio.swf',
774
+    'wp-includes/js/mediaelement/mediaelement-flash-video-hls.swf',
775
+    'wp-includes/js/mediaelement/mediaelement-flash-video-mdash.swf',
776
+    'wp-includes/js/mediaelement/mediaelement-flash-video.swf',
777
+    'wp-includes/js/mediaelement/renderers/dailymotion.js',
778
+    'wp-includes/js/mediaelement/renderers/dailymotion.min.js',
779
+    'wp-includes/js/mediaelement/renderers/facebook.js',
780
+    'wp-includes/js/mediaelement/renderers/facebook.min.js',
781
+    'wp-includes/js/mediaelement/renderers/soundcloud.js',
782
+    'wp-includes/js/mediaelement/renderers/soundcloud.min.js',
783
+    'wp-includes/js/mediaelement/renderers/twitch.js',
784
+    'wp-includes/js/mediaelement/renderers/twitch.min.js',
785
+    // 5.0
786
+    'wp-includes/js/codemirror/jshint.js',
787
+    // 5.1
788
+    'wp-includes/random_compat/random_bytes_openssl.php',
789
+    'wp-includes/js/tinymce/wp-tinymce.js.gz',
790
+    // 5.3
791
+    'wp-includes/js/wp-a11y.js',     // Moved to: wp-includes/js/dist/a11y.js
792
+    'wp-includes/js/wp-a11y.min.js', // Moved to: wp-includes/js/dist/a11y.min.js
793
+    // 5.4
794
+    'wp-admin/js/wp-fullscreen-stub.js',
795
+    'wp-admin/js/wp-fullscreen-stub.min.js',
796
+    // 5.5
797
+    'wp-admin/css/ie.css',
798
+    'wp-admin/css/ie.min.css',
799
+    'wp-admin/css/ie-rtl.css',
800
+    'wp-admin/css/ie-rtl.min.css',
801
+    // 5.6
802
+    'wp-includes/js/jquery/ui/position.min.js',
803
+    'wp-includes/js/jquery/ui/widget.min.js',
804
+    // 5.7
805
+    'wp-includes/blocks/classic/block.json',
806
+    // 5.8
807
+    'wp-admin/images/freedoms.png',
808
+    'wp-admin/images/privacy.png',
809
+    'wp-admin/images/about-badge.svg',
810
+    'wp-admin/images/about-color-palette.svg',
811
+    'wp-admin/images/about-color-palette-vert.svg',
812
+    'wp-admin/images/about-header-brushes.svg',
813
+    'wp-includes/block-patterns/large-header.php',
814
+    'wp-includes/block-patterns/heading-paragraph.php',
815
+    'wp-includes/block-patterns/quote.php',
816
+    'wp-includes/block-patterns/text-three-columns-buttons.php',
817
+    'wp-includes/block-patterns/two-buttons.php',
818
+    'wp-includes/block-patterns/two-images.php',
819
+    'wp-includes/block-patterns/three-buttons.php',
820
+    'wp-includes/block-patterns/text-two-columns-with-images.php',
821
+    'wp-includes/block-patterns/text-two-columns.php',
822
+    'wp-includes/block-patterns/large-header-button.php',
823
+    'wp-includes/blocks/subhead/block.json',
824
+    'wp-includes/blocks/subhead',
825
+    'wp-includes/css/dist/editor/editor-styles.css',
826
+    'wp-includes/css/dist/editor/editor-styles.min.css',
827
+    'wp-includes/css/dist/editor/editor-styles-rtl.css',
828
+    'wp-includes/css/dist/editor/editor-styles-rtl.min.css',
829
+    // 5.9
830
+    'wp-includes/blocks/heading/editor.css',
831
+    'wp-includes/blocks/heading/editor.min.css',
832
+    'wp-includes/blocks/heading/editor-rtl.css',
833
+    'wp-includes/blocks/heading/editor-rtl.min.css',
834
+    'wp-includes/blocks/post-content/editor.css',
835
+    'wp-includes/blocks/post-content/editor.min.css',
836
+    'wp-includes/blocks/post-content/editor-rtl.css',
837
+    'wp-includes/blocks/post-content/editor-rtl.min.css',
838
+    'wp-includes/blocks/query-title/editor.css',
839
+    'wp-includes/blocks/query-title/editor.min.css',
840
+    'wp-includes/blocks/query-title/editor-rtl.css',
841
+    'wp-includes/blocks/query-title/editor-rtl.min.css',
842
+    'wp-includes/blocks/tag-cloud/editor.css',
843
+    'wp-includes/blocks/tag-cloud/editor.min.css',
844
+    'wp-includes/blocks/tag-cloud/editor-rtl.css',
845
+    'wp-includes/blocks/tag-cloud/editor-rtl.min.css',
846
+    // 6.0
847
+    'wp-content/themes/twentytwentytwo/assets/fonts/LICENSE.md',
848 848
 );
849 849
 
850 850
 /**
@@ -871,19 +871,19 @@  discard block
 block discarded – undo
871 871
 global $_new_bundled_files;
872 872
 
873 873
 $_new_bundled_files = array(
874
-	'plugins/akismet/'        => '2.0',
875
-	'themes/twentyten/'       => '3.0',
876
-	'themes/twentyeleven/'    => '3.2',
877
-	'themes/twentytwelve/'    => '3.5',
878
-	'themes/twentythirteen/'  => '3.6',
879
-	'themes/twentyfourteen/'  => '3.8',
880
-	'themes/twentyfifteen/'   => '4.1',
881
-	'themes/twentysixteen/'   => '4.4',
882
-	'themes/twentyseventeen/' => '4.7',
883
-	'themes/twentynineteen/'  => '5.0',
884
-	'themes/twentytwenty/'    => '5.3',
885
-	'themes/twentytwentyone/' => '5.6',
886
-	'themes/twentytwentytwo/' => '5.9',
874
+    'plugins/akismet/'        => '2.0',
875
+    'themes/twentyten/'       => '3.0',
876
+    'themes/twentyeleven/'    => '3.2',
877
+    'themes/twentytwelve/'    => '3.5',
878
+    'themes/twentythirteen/'  => '3.6',
879
+    'themes/twentyfourteen/'  => '3.8',
880
+    'themes/twentyfifteen/'   => '4.1',
881
+    'themes/twentysixteen/'   => '4.4',
882
+    'themes/twentyseventeen/' => '4.7',
883
+    'themes/twentynineteen/'  => '5.0',
884
+    'themes/twentytwenty/'    => '5.3',
885
+    'themes/twentytwentyone/' => '5.6',
886
+    'themes/twentytwentytwo/' => '5.9',
887 887
 );
888 888
 
889 889
 /**
@@ -941,522 +941,522 @@  discard block
 block discarded – undo
941 941
  * @return string|WP_Error New WordPress version on success, WP_Error on failure.
942 942
  */
943 943
 function update_core( $from, $to ) {
944
-	global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
945
-
946
-	set_time_limit( 300 );
947
-
948
-	/**
949
-	 * Filters feedback messages displayed during the core update process.
950
-	 *
951
-	 * The filter is first evaluated after the zip file for the latest version
952
-	 * has been downloaded and unzipped. It is evaluated five more times during
953
-	 * the process:
954
-	 *
955
-	 * 1. Before WordPress begins the core upgrade process.
956
-	 * 2. Before Maintenance Mode is enabled.
957
-	 * 3. Before WordPress begins copying over the necessary files.
958
-	 * 4. Before Maintenance Mode is disabled.
959
-	 * 5. Before the database is upgraded.
960
-	 *
961
-	 * @since 2.5.0
962
-	 *
963
-	 * @param string $feedback The core update feedback messages.
964
-	 */
965
-	apply_filters( 'update_feedback', __( 'Verifying the unpacked files&#8230;' ) );
966
-
967
-	// Sanity check the unzipped distribution.
968
-	$distro = '';
969
-	$roots  = array( '/wordpress/', '/wordpress-mu/' );
970
-
971
-	foreach ( $roots as $root ) {
972
-		if ( $wp_filesystem->exists( $from . $root . 'readme.html' )
973
-			&& $wp_filesystem->exists( $from . $root . 'wp-includes/version.php' )
974
-		) {
975
-			$distro = $root;
976
-			break;
977
-		}
978
-	}
979
-
980
-	if ( ! $distro ) {
981
-		$wp_filesystem->delete( $from, true );
982
-
983
-		return new WP_Error( 'insane_distro', __( 'The update could not be unpacked' ) );
984
-	}
985
-
986
-	/*
944
+    global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
945
+
946
+    set_time_limit( 300 );
947
+
948
+    /**
949
+     * Filters feedback messages displayed during the core update process.
950
+     *
951
+     * The filter is first evaluated after the zip file for the latest version
952
+     * has been downloaded and unzipped. It is evaluated five more times during
953
+     * the process:
954
+     *
955
+     * 1. Before WordPress begins the core upgrade process.
956
+     * 2. Before Maintenance Mode is enabled.
957
+     * 3. Before WordPress begins copying over the necessary files.
958
+     * 4. Before Maintenance Mode is disabled.
959
+     * 5. Before the database is upgraded.
960
+     *
961
+     * @since 2.5.0
962
+     *
963
+     * @param string $feedback The core update feedback messages.
964
+     */
965
+    apply_filters( 'update_feedback', __( 'Verifying the unpacked files&#8230;' ) );
966
+
967
+    // Sanity check the unzipped distribution.
968
+    $distro = '';
969
+    $roots  = array( '/wordpress/', '/wordpress-mu/' );
970
+
971
+    foreach ( $roots as $root ) {
972
+        if ( $wp_filesystem->exists( $from . $root . 'readme.html' )
973
+            && $wp_filesystem->exists( $from . $root . 'wp-includes/version.php' )
974
+        ) {
975
+            $distro = $root;
976
+            break;
977
+        }
978
+    }
979
+
980
+    if ( ! $distro ) {
981
+        $wp_filesystem->delete( $from, true );
982
+
983
+        return new WP_Error( 'insane_distro', __( 'The update could not be unpacked' ) );
984
+    }
985
+
986
+    /*
987 987
 	 * Import $wp_version, $required_php_version, and $required_mysql_version from the new version.
988 988
 	 * DO NOT globalize any variables imported from `version-current.php` in this function.
989 989
 	 *
990 990
 	 * BC Note: $wp_filesystem->wp_content_dir() returned unslashed pre-2.8.
991 991
 	 */
992
-	$versions_file = trailingslashit( $wp_filesystem->wp_content_dir() ) . 'upgrade/version-current.php';
992
+    $versions_file = trailingslashit( $wp_filesystem->wp_content_dir() ) . 'upgrade/version-current.php';
993 993
 
994
-	if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $versions_file ) ) {
995
-		$wp_filesystem->delete( $from, true );
994
+    if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $versions_file ) ) {
995
+        $wp_filesystem->delete( $from, true );
996 996
 
997
-		return new WP_Error(
998
-			'copy_failed_for_version_file',
999
-			__( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ),
1000
-			'wp-includes/version.php'
1001
-		);
1002
-	}
997
+        return new WP_Error(
998
+            'copy_failed_for_version_file',
999
+            __( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ),
1000
+            'wp-includes/version.php'
1001
+        );
1002
+    }
1003 1003
 
1004
-	$wp_filesystem->chmod( $versions_file, FS_CHMOD_FILE );
1004
+    $wp_filesystem->chmod( $versions_file, FS_CHMOD_FILE );
1005 1005
 
1006
-	/*
1006
+    /*
1007 1007
 	 * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
1008 1008
 	 * so don't run it when upgrading from older versions.
1009 1009
 	 */
1010
-	if ( function_exists( 'wp_opcache_invalidate' ) ) {
1011
-		wp_opcache_invalidate( $versions_file );
1012
-	}
1013
-
1014
-	require WP_CONTENT_DIR . '/upgrade/version-current.php';
1015
-	$wp_filesystem->delete( $versions_file );
1016
-
1017
-	$php_version       = phpversion();
1018
-	$mysql_version     = $wpdb->db_version();
1019
-	$old_wp_version    = $GLOBALS['wp_version']; // The version of WordPress we're updating from.
1020
-	$development_build = ( false !== strpos( $old_wp_version . $wp_version, '-' ) ); // A dash in the version indicates a development release.
1021
-	$php_compat        = version_compare( $php_version, $required_php_version, '>=' );
1022
-
1023
-	if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) {
1024
-		$mysql_compat = true;
1025
-	} else {
1026
-		$mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' );
1027
-	}
1028
-
1029
-	if ( ! $mysql_compat || ! $php_compat ) {
1030
-		$wp_filesystem->delete( $from, true );
1031
-	}
1032
-
1033
-	$php_update_message = '';
1034
-
1035
-	if ( function_exists( 'wp_get_update_php_url' ) ) {
1036
-		$php_update_message = '</p><p>' . sprintf(
1037
-			/* translators: %s: URL to Update PHP page. */
1038
-			__( '<a href="%s">Learn more about updating PHP</a>.' ),
1039
-			esc_url( wp_get_update_php_url() )
1040
-		);
1041
-
1042
-		if ( function_exists( 'wp_get_update_php_annotation' ) ) {
1043
-			$annotation = wp_get_update_php_annotation();
1044
-
1045
-			if ( $annotation ) {
1046
-				$php_update_message .= '</p><p><em>' . $annotation . '</em>';
1047
-			}
1048
-		}
1049
-	}
1050
-
1051
-	if ( ! $mysql_compat && ! $php_compat ) {
1052
-		return new WP_Error(
1053
-			'php_mysql_not_compatible',
1054
-			sprintf(
1055
-				/* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Minimum required MySQL version number, 4: Current PHP version number, 5: Current MySQL version number. */
1056
-				__( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.' ),
1057
-				$wp_version,
1058
-				$required_php_version,
1059
-				$required_mysql_version,
1060
-				$php_version,
1061
-				$mysql_version
1062
-			) . $php_update_message
1063
-		);
1064
-	} elseif ( ! $php_compat ) {
1065
-		return new WP_Error(
1066
-			'php_not_compatible',
1067
-			sprintf(
1068
-				/* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Current PHP version number. */
1069
-				__( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.' ),
1070
-				$wp_version,
1071
-				$required_php_version,
1072
-				$php_version
1073
-			) . $php_update_message
1074
-		);
1075
-	} elseif ( ! $mysql_compat ) {
1076
-		return new WP_Error(
1077
-			'mysql_not_compatible',
1078
-			sprintf(
1079
-				/* translators: 1: WordPress version number, 2: Minimum required MySQL version number, 3: Current MySQL version number. */
1080
-				__( 'The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.' ),
1081
-				$wp_version,
1082
-				$required_mysql_version,
1083
-				$mysql_version
1084
-			)
1085
-		);
1086
-	}
1087
-
1088
-	// Add a warning when the JSON PHP extension is missing.
1089
-	if ( ! extension_loaded( 'json' ) ) {
1090
-		return new WP_Error(
1091
-			'php_not_compatible_json',
1092
-			sprintf(
1093
-				/* translators: 1: WordPress version number, 2: The PHP extension name needed. */
1094
-				__( 'The update cannot be installed because WordPress %1$s requires the %2$s PHP extension.' ),
1095
-				$wp_version,
1096
-				'JSON'
1097
-			)
1098
-		);
1099
-	}
1100
-
1101
-	/** This filter is documented in wp-admin/includes/update-core.php */
1102
-	apply_filters( 'update_feedback', __( 'Preparing to install the latest version&#8230;' ) );
1103
-
1104
-	// Don't copy wp-content, we'll deal with that below.
1105
-	// We also copy version.php last so failed updates report their old version.
1106
-	$skip              = array( 'wp-content', 'wp-includes/version.php' );
1107
-	$check_is_writable = array();
1108
-
1109
-	// Check to see which files don't really need updating - only available for 3.7 and higher.
1110
-	if ( function_exists( 'get_core_checksums' ) ) {
1111
-		// Find the local version of the working directory.
1112
-		$working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro;
1113
-
1114
-		$checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );
1115
-
1116
-		if ( is_array( $checksums ) && isset( $checksums[ $wp_version ] ) ) {
1117
-			$checksums = $checksums[ $wp_version ]; // Compat code for 3.7-beta2.
1118
-		}
1119
-
1120
-		if ( is_array( $checksums ) ) {
1121
-			foreach ( $checksums as $file => $checksum ) {
1122
-				if ( 'wp-content' === substr( $file, 0, 10 ) ) {
1123
-					continue;
1124
-				}
1125
-
1126
-				if ( ! file_exists( ABSPATH . $file ) ) {
1127
-					continue;
1128
-				}
1129
-
1130
-				if ( ! file_exists( $working_dir_local . $file ) ) {
1131
-					continue;
1132
-				}
1133
-
1134
-				if ( '.' === dirname( $file )
1135
-					&& in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
1136
-				) {
1137
-					continue;
1138
-				}
1139
-
1140
-				if ( md5_file( ABSPATH . $file ) === $checksum ) {
1141
-					$skip[] = $file;
1142
-				} else {
1143
-					$check_is_writable[ $file ] = ABSPATH . $file;
1144
-				}
1145
-			}
1146
-		}
1147
-	}
1148
-
1149
-	// If we're using the direct method, we can predict write failures that are due to permissions.
1150
-	if ( $check_is_writable && 'direct' === $wp_filesystem->method ) {
1151
-		$files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) );
1152
-
1153
-		if ( $files_writable !== $check_is_writable ) {
1154
-			$files_not_writable = array_diff_key( $check_is_writable, $files_writable );
1155
-
1156
-			foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) {
1157
-				// If the writable check failed, chmod file to 0644 and try again, same as copy_dir().
1158
-				$wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE );
1159
-
1160
-				if ( $wp_filesystem->is_writable( $file_not_writable ) ) {
1161
-					unset( $files_not_writable[ $relative_file_not_writable ] );
1162
-				}
1163
-			}
1164
-
1165
-			// Store package-relative paths (the key) of non-writable files in the WP_Error object.
1166
-			$error_data = version_compare( $old_wp_version, '3.7-beta2', '>' ) ? array_keys( $files_not_writable ) : '';
1167
-
1168
-			if ( $files_not_writable ) {
1169
-				return new WP_Error(
1170
-					'files_not_writable',
1171
-					__( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ),
1172
-					implode( ', ', $error_data )
1173
-				);
1174
-			}
1175
-		}
1176
-	}
1177
-
1178
-	/** This filter is documented in wp-admin/includes/update-core.php */
1179
-	apply_filters( 'update_feedback', __( 'Enabling Maintenance mode&#8230;' ) );
1180
-
1181
-	// Create maintenance file to signal that we are upgrading.
1182
-	$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
1183
-	$maintenance_file   = $to . '.maintenance';
1184
-	$wp_filesystem->delete( $maintenance_file );
1185
-	$wp_filesystem->put_contents( $maintenance_file, $maintenance_string, FS_CHMOD_FILE );
1186
-
1187
-	/** This filter is documented in wp-admin/includes/update-core.php */
1188
-	apply_filters( 'update_feedback', __( 'Copying the required files&#8230;' ) );
1189
-
1190
-	// Copy new versions of WP files into place.
1191
-	$result = _copy_dir( $from . $distro, $to, $skip );
1192
-
1193
-	if ( is_wp_error( $result ) ) {
1194
-		$result = new WP_Error(
1195
-			$result->get_error_code(),
1196
-			$result->get_error_message(),
1197
-			substr( $result->get_error_data(), strlen( $to ) )
1198
-		);
1199
-	}
1200
-
1201
-	// Since we know the core files have copied over, we can now copy the version file.
1202
-	if ( ! is_wp_error( $result ) ) {
1203
-		if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $to . 'wp-includes/version.php', true /* overwrite */ ) ) {
1204
-			$wp_filesystem->delete( $from, true );
1205
-			$result = new WP_Error(
1206
-				'copy_failed_for_version_file',
1207
-				__( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ),
1208
-				'wp-includes/version.php'
1209
-			);
1210
-		}
1211
-
1212
-		$wp_filesystem->chmod( $to . 'wp-includes/version.php', FS_CHMOD_FILE );
1213
-
1214
-		/*
1010
+    if ( function_exists( 'wp_opcache_invalidate' ) ) {
1011
+        wp_opcache_invalidate( $versions_file );
1012
+    }
1013
+
1014
+    require WP_CONTENT_DIR . '/upgrade/version-current.php';
1015
+    $wp_filesystem->delete( $versions_file );
1016
+
1017
+    $php_version       = phpversion();
1018
+    $mysql_version     = $wpdb->db_version();
1019
+    $old_wp_version    = $GLOBALS['wp_version']; // The version of WordPress we're updating from.
1020
+    $development_build = ( false !== strpos( $old_wp_version . $wp_version, '-' ) ); // A dash in the version indicates a development release.
1021
+    $php_compat        = version_compare( $php_version, $required_php_version, '>=' );
1022
+
1023
+    if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) {
1024
+        $mysql_compat = true;
1025
+    } else {
1026
+        $mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' );
1027
+    }
1028
+
1029
+    if ( ! $mysql_compat || ! $php_compat ) {
1030
+        $wp_filesystem->delete( $from, true );
1031
+    }
1032
+
1033
+    $php_update_message = '';
1034
+
1035
+    if ( function_exists( 'wp_get_update_php_url' ) ) {
1036
+        $php_update_message = '</p><p>' . sprintf(
1037
+            /* translators: %s: URL to Update PHP page. */
1038
+            __( '<a href="%s">Learn more about updating PHP</a>.' ),
1039
+            esc_url( wp_get_update_php_url() )
1040
+        );
1041
+
1042
+        if ( function_exists( 'wp_get_update_php_annotation' ) ) {
1043
+            $annotation = wp_get_update_php_annotation();
1044
+
1045
+            if ( $annotation ) {
1046
+                $php_update_message .= '</p><p><em>' . $annotation . '</em>';
1047
+            }
1048
+        }
1049
+    }
1050
+
1051
+    if ( ! $mysql_compat && ! $php_compat ) {
1052
+        return new WP_Error(
1053
+            'php_mysql_not_compatible',
1054
+            sprintf(
1055
+                /* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Minimum required MySQL version number, 4: Current PHP version number, 5: Current MySQL version number. */
1056
+                __( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.' ),
1057
+                $wp_version,
1058
+                $required_php_version,
1059
+                $required_mysql_version,
1060
+                $php_version,
1061
+                $mysql_version
1062
+            ) . $php_update_message
1063
+        );
1064
+    } elseif ( ! $php_compat ) {
1065
+        return new WP_Error(
1066
+            'php_not_compatible',
1067
+            sprintf(
1068
+                /* translators: 1: WordPress version number, 2: Minimum required PHP version number, 3: Current PHP version number. */
1069
+                __( 'The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.' ),
1070
+                $wp_version,
1071
+                $required_php_version,
1072
+                $php_version
1073
+            ) . $php_update_message
1074
+        );
1075
+    } elseif ( ! $mysql_compat ) {
1076
+        return new WP_Error(
1077
+            'mysql_not_compatible',
1078
+            sprintf(
1079
+                /* translators: 1: WordPress version number, 2: Minimum required MySQL version number, 3: Current MySQL version number. */
1080
+                __( 'The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.' ),
1081
+                $wp_version,
1082
+                $required_mysql_version,
1083
+                $mysql_version
1084
+            )
1085
+        );
1086
+    }
1087
+
1088
+    // Add a warning when the JSON PHP extension is missing.
1089
+    if ( ! extension_loaded( 'json' ) ) {
1090
+        return new WP_Error(
1091
+            'php_not_compatible_json',
1092
+            sprintf(
1093
+                /* translators: 1: WordPress version number, 2: The PHP extension name needed. */
1094
+                __( 'The update cannot be installed because WordPress %1$s requires the %2$s PHP extension.' ),
1095
+                $wp_version,
1096
+                'JSON'
1097
+            )
1098
+        );
1099
+    }
1100
+
1101
+    /** This filter is documented in wp-admin/includes/update-core.php */
1102
+    apply_filters( 'update_feedback', __( 'Preparing to install the latest version&#8230;' ) );
1103
+
1104
+    // Don't copy wp-content, we'll deal with that below.
1105
+    // We also copy version.php last so failed updates report their old version.
1106
+    $skip              = array( 'wp-content', 'wp-includes/version.php' );
1107
+    $check_is_writable = array();
1108
+
1109
+    // Check to see which files don't really need updating - only available for 3.7 and higher.
1110
+    if ( function_exists( 'get_core_checksums' ) ) {
1111
+        // Find the local version of the working directory.
1112
+        $working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename( $from ) . $distro;
1113
+
1114
+        $checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );
1115
+
1116
+        if ( is_array( $checksums ) && isset( $checksums[ $wp_version ] ) ) {
1117
+            $checksums = $checksums[ $wp_version ]; // Compat code for 3.7-beta2.
1118
+        }
1119
+
1120
+        if ( is_array( $checksums ) ) {
1121
+            foreach ( $checksums as $file => $checksum ) {
1122
+                if ( 'wp-content' === substr( $file, 0, 10 ) ) {
1123
+                    continue;
1124
+                }
1125
+
1126
+                if ( ! file_exists( ABSPATH . $file ) ) {
1127
+                    continue;
1128
+                }
1129
+
1130
+                if ( ! file_exists( $working_dir_local . $file ) ) {
1131
+                    continue;
1132
+                }
1133
+
1134
+                if ( '.' === dirname( $file )
1135
+                    && in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
1136
+                ) {
1137
+                    continue;
1138
+                }
1139
+
1140
+                if ( md5_file( ABSPATH . $file ) === $checksum ) {
1141
+                    $skip[] = $file;
1142
+                } else {
1143
+                    $check_is_writable[ $file ] = ABSPATH . $file;
1144
+                }
1145
+            }
1146
+        }
1147
+    }
1148
+
1149
+    // If we're using the direct method, we can predict write failures that are due to permissions.
1150
+    if ( $check_is_writable && 'direct' === $wp_filesystem->method ) {
1151
+        $files_writable = array_filter( $check_is_writable, array( $wp_filesystem, 'is_writable' ) );
1152
+
1153
+        if ( $files_writable !== $check_is_writable ) {
1154
+            $files_not_writable = array_diff_key( $check_is_writable, $files_writable );
1155
+
1156
+            foreach ( $files_not_writable as $relative_file_not_writable => $file_not_writable ) {
1157
+                // If the writable check failed, chmod file to 0644 and try again, same as copy_dir().
1158
+                $wp_filesystem->chmod( $file_not_writable, FS_CHMOD_FILE );
1159
+
1160
+                if ( $wp_filesystem->is_writable( $file_not_writable ) ) {
1161
+                    unset( $files_not_writable[ $relative_file_not_writable ] );
1162
+                }
1163
+            }
1164
+
1165
+            // Store package-relative paths (the key) of non-writable files in the WP_Error object.
1166
+            $error_data = version_compare( $old_wp_version, '3.7-beta2', '>' ) ? array_keys( $files_not_writable ) : '';
1167
+
1168
+            if ( $files_not_writable ) {
1169
+                return new WP_Error(
1170
+                    'files_not_writable',
1171
+                    __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ),
1172
+                    implode( ', ', $error_data )
1173
+                );
1174
+            }
1175
+        }
1176
+    }
1177
+
1178
+    /** This filter is documented in wp-admin/includes/update-core.php */
1179
+    apply_filters( 'update_feedback', __( 'Enabling Maintenance mode&#8230;' ) );
1180
+
1181
+    // Create maintenance file to signal that we are upgrading.
1182
+    $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
1183
+    $maintenance_file   = $to . '.maintenance';
1184
+    $wp_filesystem->delete( $maintenance_file );
1185
+    $wp_filesystem->put_contents( $maintenance_file, $maintenance_string, FS_CHMOD_FILE );
1186
+
1187
+    /** This filter is documented in wp-admin/includes/update-core.php */
1188
+    apply_filters( 'update_feedback', __( 'Copying the required files&#8230;' ) );
1189
+
1190
+    // Copy new versions of WP files into place.
1191
+    $result = _copy_dir( $from . $distro, $to, $skip );
1192
+
1193
+    if ( is_wp_error( $result ) ) {
1194
+        $result = new WP_Error(
1195
+            $result->get_error_code(),
1196
+            $result->get_error_message(),
1197
+            substr( $result->get_error_data(), strlen( $to ) )
1198
+        );
1199
+    }
1200
+
1201
+    // Since we know the core files have copied over, we can now copy the version file.
1202
+    if ( ! is_wp_error( $result ) ) {
1203
+        if ( ! $wp_filesystem->copy( $from . $distro . 'wp-includes/version.php', $to . 'wp-includes/version.php', true /* overwrite */ ) ) {
1204
+            $wp_filesystem->delete( $from, true );
1205
+            $result = new WP_Error(
1206
+                'copy_failed_for_version_file',
1207
+                __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ),
1208
+                'wp-includes/version.php'
1209
+            );
1210
+        }
1211
+
1212
+        $wp_filesystem->chmod( $to . 'wp-includes/version.php', FS_CHMOD_FILE );
1213
+
1214
+        /*
1215 1215
 		 * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
1216 1216
 		 * so don't run it when upgrading from older versions.
1217 1217
 		 */
1218
-		if ( function_exists( 'wp_opcache_invalidate' ) ) {
1219
-			wp_opcache_invalidate( $to . 'wp-includes/version.php' );
1220
-		}
1221
-	}
1222
-
1223
-	// Check to make sure everything copied correctly, ignoring the contents of wp-content.
1224
-	$skip   = array( 'wp-content' );
1225
-	$failed = array();
1226
-
1227
-	if ( isset( $checksums ) && is_array( $checksums ) ) {
1228
-		foreach ( $checksums as $file => $checksum ) {
1229
-			if ( 'wp-content' === substr( $file, 0, 10 ) ) {
1230
-				continue;
1231
-			}
1232
-
1233
-			if ( ! file_exists( $working_dir_local . $file ) ) {
1234
-				continue;
1235
-			}
1236
-
1237
-			if ( '.' === dirname( $file )
1238
-				&& in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
1239
-			) {
1240
-				$skip[] = $file;
1241
-				continue;
1242
-			}
1243
-
1244
-			if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) === $checksum ) {
1245
-				$skip[] = $file;
1246
-			} else {
1247
-				$failed[] = $file;
1248
-			}
1249
-		}
1250
-	}
1251
-
1252
-	// Some files didn't copy properly.
1253
-	if ( ! empty( $failed ) ) {
1254
-		$total_size = 0;
1255
-
1256
-		foreach ( $failed as $file ) {
1257
-			if ( file_exists( $working_dir_local . $file ) ) {
1258
-				$total_size += filesize( $working_dir_local . $file );
1259
-			}
1260
-		}
1261
-
1262
-		// If we don't have enough free space, it isn't worth trying again.
1263
-		// Unlikely to be hit due to the check in unzip_file().
1264
-		$available_space = function_exists( 'disk_free_space' ) ? @disk_free_space( ABSPATH ) : false;
1265
-
1266
-		if ( $available_space && $total_size >= $available_space ) {
1267
-			$result = new WP_Error( 'disk_full', __( 'There is not enough free disk space to complete the update.' ) );
1268
-		} else {
1269
-			$result = _copy_dir( $from . $distro, $to, $skip );
1270
-
1271
-			if ( is_wp_error( $result ) ) {
1272
-				$result = new WP_Error(
1273
-					$result->get_error_code() . '_retry',
1274
-					$result->get_error_message(),
1275
-					substr( $result->get_error_data(), strlen( $to ) )
1276
-				);
1277
-			}
1278
-		}
1279
-	}
1280
-
1281
-	// Custom content directory needs updating now.
1282
-	// Copy languages.
1283
-	if ( ! is_wp_error( $result ) && $wp_filesystem->is_dir( $from . $distro . 'wp-content/languages' ) ) {
1284
-		if ( WP_LANG_DIR !== ABSPATH . WPINC . '/languages' || @is_dir( WP_LANG_DIR ) ) {
1285
-			$lang_dir = WP_LANG_DIR;
1286
-		} else {
1287
-			$lang_dir = WP_CONTENT_DIR . '/languages';
1288
-		}
1289
-
1290
-		// Check if the language directory exists first.
1291
-		if ( ! @is_dir( $lang_dir ) && 0 === strpos( $lang_dir, ABSPATH ) ) {
1292
-			// If it's within the ABSPATH we can handle it here, otherwise they're out of luck.
1293
-			$wp_filesystem->mkdir( $to . str_replace( ABSPATH, '', $lang_dir ), FS_CHMOD_DIR );
1294
-			clearstatcache(); // For FTP, need to clear the stat cache.
1295
-		}
1296
-
1297
-		if ( @is_dir( $lang_dir ) ) {
1298
-			$wp_lang_dir = $wp_filesystem->find_folder( $lang_dir );
1299
-
1300
-			if ( $wp_lang_dir ) {
1301
-				$result = copy_dir( $from . $distro . 'wp-content/languages/', $wp_lang_dir );
1302
-
1303
-				if ( is_wp_error( $result ) ) {
1304
-					$result = new WP_Error(
1305
-						$result->get_error_code() . '_languages',
1306
-						$result->get_error_message(),
1307
-						substr( $result->get_error_data(), strlen( $wp_lang_dir ) )
1308
-					);
1309
-				}
1310
-			}
1311
-		}
1312
-	}
1313
-
1314
-	/** This filter is documented in wp-admin/includes/update-core.php */
1315
-	apply_filters( 'update_feedback', __( 'Disabling Maintenance mode&#8230;' ) );
1316
-
1317
-	// Remove maintenance file, we're done with potential site-breaking changes.
1318
-	$wp_filesystem->delete( $maintenance_file );
1319
-
1320
-	// 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users,
1321
-	// preventing installation of Twenty Twelve.
1322
-	if ( '3.5' === $old_wp_version ) {
1323
-		if ( is_dir( WP_CONTENT_DIR . '/themes/twentytwelve' )
1324
-			&& ! file_exists( WP_CONTENT_DIR . '/themes/twentytwelve/style.css' )
1325
-		) {
1326
-			$wp_filesystem->delete( $wp_filesystem->wp_themes_dir() . 'twentytwelve/' );
1327
-		}
1328
-	}
1329
-
1330
-	/*
1218
+        if ( function_exists( 'wp_opcache_invalidate' ) ) {
1219
+            wp_opcache_invalidate( $to . 'wp-includes/version.php' );
1220
+        }
1221
+    }
1222
+
1223
+    // Check to make sure everything copied correctly, ignoring the contents of wp-content.
1224
+    $skip   = array( 'wp-content' );
1225
+    $failed = array();
1226
+
1227
+    if ( isset( $checksums ) && is_array( $checksums ) ) {
1228
+        foreach ( $checksums as $file => $checksum ) {
1229
+            if ( 'wp-content' === substr( $file, 0, 10 ) ) {
1230
+                continue;
1231
+            }
1232
+
1233
+            if ( ! file_exists( $working_dir_local . $file ) ) {
1234
+                continue;
1235
+            }
1236
+
1237
+            if ( '.' === dirname( $file )
1238
+                && in_array( pathinfo( $file, PATHINFO_EXTENSION ), array( 'html', 'txt' ), true )
1239
+            ) {
1240
+                $skip[] = $file;
1241
+                continue;
1242
+            }
1243
+
1244
+            if ( file_exists( ABSPATH . $file ) && md5_file( ABSPATH . $file ) === $checksum ) {
1245
+                $skip[] = $file;
1246
+            } else {
1247
+                $failed[] = $file;
1248
+            }
1249
+        }
1250
+    }
1251
+
1252
+    // Some files didn't copy properly.
1253
+    if ( ! empty( $failed ) ) {
1254
+        $total_size = 0;
1255
+
1256
+        foreach ( $failed as $file ) {
1257
+            if ( file_exists( $working_dir_local . $file ) ) {
1258
+                $total_size += filesize( $working_dir_local . $file );
1259
+            }
1260
+        }
1261
+
1262
+        // If we don't have enough free space, it isn't worth trying again.
1263
+        // Unlikely to be hit due to the check in unzip_file().
1264
+        $available_space = function_exists( 'disk_free_space' ) ? @disk_free_space( ABSPATH ) : false;
1265
+
1266
+        if ( $available_space && $total_size >= $available_space ) {
1267
+            $result = new WP_Error( 'disk_full', __( 'There is not enough free disk space to complete the update.' ) );
1268
+        } else {
1269
+            $result = _copy_dir( $from . $distro, $to, $skip );
1270
+
1271
+            if ( is_wp_error( $result ) ) {
1272
+                $result = new WP_Error(
1273
+                    $result->get_error_code() . '_retry',
1274
+                    $result->get_error_message(),
1275
+                    substr( $result->get_error_data(), strlen( $to ) )
1276
+                );
1277
+            }
1278
+        }
1279
+    }
1280
+
1281
+    // Custom content directory needs updating now.
1282
+    // Copy languages.
1283
+    if ( ! is_wp_error( $result ) && $wp_filesystem->is_dir( $from . $distro . 'wp-content/languages' ) ) {
1284
+        if ( WP_LANG_DIR !== ABSPATH . WPINC . '/languages' || @is_dir( WP_LANG_DIR ) ) {
1285
+            $lang_dir = WP_LANG_DIR;
1286
+        } else {
1287
+            $lang_dir = WP_CONTENT_DIR . '/languages';
1288
+        }
1289
+
1290
+        // Check if the language directory exists first.
1291
+        if ( ! @is_dir( $lang_dir ) && 0 === strpos( $lang_dir, ABSPATH ) ) {
1292
+            // If it's within the ABSPATH we can handle it here, otherwise they're out of luck.
1293
+            $wp_filesystem->mkdir( $to . str_replace( ABSPATH, '', $lang_dir ), FS_CHMOD_DIR );
1294
+            clearstatcache(); // For FTP, need to clear the stat cache.
1295
+        }
1296
+
1297
+        if ( @is_dir( $lang_dir ) ) {
1298
+            $wp_lang_dir = $wp_filesystem->find_folder( $lang_dir );
1299
+
1300
+            if ( $wp_lang_dir ) {
1301
+                $result = copy_dir( $from . $distro . 'wp-content/languages/', $wp_lang_dir );
1302
+
1303
+                if ( is_wp_error( $result ) ) {
1304
+                    $result = new WP_Error(
1305
+                        $result->get_error_code() . '_languages',
1306
+                        $result->get_error_message(),
1307
+                        substr( $result->get_error_data(), strlen( $wp_lang_dir ) )
1308
+                    );
1309
+                }
1310
+            }
1311
+        }
1312
+    }
1313
+
1314
+    /** This filter is documented in wp-admin/includes/update-core.php */
1315
+    apply_filters( 'update_feedback', __( 'Disabling Maintenance mode&#8230;' ) );
1316
+
1317
+    // Remove maintenance file, we're done with potential site-breaking changes.
1318
+    $wp_filesystem->delete( $maintenance_file );
1319
+
1320
+    // 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users,
1321
+    // preventing installation of Twenty Twelve.
1322
+    if ( '3.5' === $old_wp_version ) {
1323
+        if ( is_dir( WP_CONTENT_DIR . '/themes/twentytwelve' )
1324
+            && ! file_exists( WP_CONTENT_DIR . '/themes/twentytwelve/style.css' )
1325
+        ) {
1326
+            $wp_filesystem->delete( $wp_filesystem->wp_themes_dir() . 'twentytwelve/' );
1327
+        }
1328
+    }
1329
+
1330
+    /*
1331 1331
 	 * Copy new bundled plugins & themes.
1332 1332
 	 * This gives us the ability to install new plugins & themes bundled with
1333 1333
 	 * future versions of WordPress whilst avoiding the re-install upon upgrade issue.
1334 1334
 	 * $development_build controls us overwriting bundled themes and plugins when a non-stable release is being updated.
1335 1335
 	 */
1336
-	if ( ! is_wp_error( $result )
1337
-		&& ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED )
1338
-	) {
1339
-		foreach ( (array) $_new_bundled_files as $file => $introduced_version ) {
1340
-			// If a $development_build or if $introduced version is greater than what the site was previously running.
1341
-			if ( $development_build || version_compare( $introduced_version, $old_wp_version, '>' ) ) {
1342
-				$directory = ( '/' === $file[ strlen( $file ) - 1 ] );
1343
-
1344
-				list( $type, $filename ) = explode( '/', $file, 2 );
1345
-
1346
-				// Check to see if the bundled items exist before attempting to copy them.
1347
-				if ( ! $wp_filesystem->exists( $from . $distro . 'wp-content/' . $file ) ) {
1348
-					continue;
1349
-				}
1350
-
1351
-				if ( 'plugins' === $type ) {
1352
-					$dest = $wp_filesystem->wp_plugins_dir();
1353
-				} elseif ( 'themes' === $type ) {
1354
-					// Back-compat, ::wp_themes_dir() did not return trailingslash'd pre-3.2.
1355
-					$dest = trailingslashit( $wp_filesystem->wp_themes_dir() );
1356
-				} else {
1357
-					continue;
1358
-				}
1359
-
1360
-				if ( ! $directory ) {
1361
-					if ( ! $development_build && $wp_filesystem->exists( $dest . $filename ) ) {
1362
-						continue;
1363
-					}
1364
-
1365
-					if ( ! $wp_filesystem->copy( $from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE ) ) {
1366
-						$result = new WP_Error( "copy_failed_for_new_bundled_$type", __( 'Could not copy file.' ), $dest . $filename );
1367
-					}
1368
-				} else {
1369
-					if ( ! $development_build && $wp_filesystem->is_dir( $dest . $filename ) ) {
1370
-						continue;
1371
-					}
1372
-
1373
-					$wp_filesystem->mkdir( $dest . $filename, FS_CHMOD_DIR );
1374
-					$_result = copy_dir( $from . $distro . 'wp-content/' . $file, $dest . $filename );
1375
-
1376
-					// If a error occurs partway through this final step, keep the error flowing through, but keep process going.
1377
-					if ( is_wp_error( $_result ) ) {
1378
-						if ( ! is_wp_error( $result ) ) {
1379
-							$result = new WP_Error;
1380
-						}
1381
-
1382
-						$result->add(
1383
-							$_result->get_error_code() . "_$type",
1384
-							$_result->get_error_message(),
1385
-							substr( $_result->get_error_data(), strlen( $dest ) )
1386
-						);
1387
-					}
1388
-				}
1389
-			}
1390
-		} // End foreach.
1391
-	}
1392
-
1393
-	// Handle $result error from the above blocks.
1394
-	if ( is_wp_error( $result ) ) {
1395
-		$wp_filesystem->delete( $from, true );
1396
-
1397
-		return $result;
1398
-	}
1399
-
1400
-	// Remove old files.
1401
-	foreach ( $_old_files as $old_file ) {
1402
-		$old_file = $to . $old_file;
1403
-
1404
-		if ( ! $wp_filesystem->exists( $old_file ) ) {
1405
-			continue;
1406
-		}
1407
-
1408
-		// If the file isn't deleted, try writing an empty string to the file instead.
1409
-		if ( ! $wp_filesystem->delete( $old_file, true ) && $wp_filesystem->is_file( $old_file ) ) {
1410
-			$wp_filesystem->put_contents( $old_file, '' );
1411
-		}
1412
-	}
1413
-
1414
-	// Remove any Genericons example.html's from the filesystem.
1415
-	_upgrade_422_remove_genericons();
1416
-
1417
-	// Deactivate the REST API plugin if its version is 2.0 Beta 4 or lower.
1418
-	_upgrade_440_force_deactivate_incompatible_plugins();
1419
-
1420
-	// Deactivate the Gutenberg plugin if its version is 11.8 or lower.
1421
-	_upgrade_590_force_deactivate_incompatible_plugins();
1422
-
1423
-	// Upgrade DB with separate request.
1424
-	/** This filter is documented in wp-admin/includes/update-core.php */
1425
-	apply_filters( 'update_feedback', __( 'Upgrading database&#8230;' ) );
1426
-
1427
-	$db_upgrade_url = admin_url( 'upgrade.php?step=upgrade_db' );
1428
-	wp_remote_post( $db_upgrade_url, array( 'timeout' => 60 ) );
1429
-
1430
-	// Clear the cache to prevent an update_option() from saving a stale db_version to the cache.
1431
-	wp_cache_flush();
1432
-	// Not all cache back ends listen to 'flush'.
1433
-	wp_cache_delete( 'alloptions', 'options' );
1434
-
1435
-	// Remove working directory.
1436
-	$wp_filesystem->delete( $from, true );
1437
-
1438
-	// Force refresh of update information.
1439
-	if ( function_exists( 'delete_site_transient' ) ) {
1440
-		delete_site_transient( 'update_core' );
1441
-	} else {
1442
-		delete_option( 'update_core' );
1443
-	}
1444
-
1445
-	/**
1446
-	 * Fires after WordPress core has been successfully updated.
1447
-	 *
1448
-	 * @since 3.3.0
1449
-	 *
1450
-	 * @param string $wp_version The current WordPress version.
1451
-	 */
1452
-	do_action( '_core_updated_successfully', $wp_version );
1453
-
1454
-	// Clear the option that blocks auto-updates after failures, now that we've been successful.
1455
-	if ( function_exists( 'delete_site_option' ) ) {
1456
-		delete_site_option( 'auto_core_update_failed' );
1457
-	}
1458
-
1459
-	return $wp_version;
1336
+    if ( ! is_wp_error( $result )
1337
+        && ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED )
1338
+    ) {
1339
+        foreach ( (array) $_new_bundled_files as $file => $introduced_version ) {
1340
+            // If a $development_build or if $introduced version is greater than what the site was previously running.
1341
+            if ( $development_build || version_compare( $introduced_version, $old_wp_version, '>' ) ) {
1342
+                $directory = ( '/' === $file[ strlen( $file ) - 1 ] );
1343
+
1344
+                list( $type, $filename ) = explode( '/', $file, 2 );
1345
+
1346
+                // Check to see if the bundled items exist before attempting to copy them.
1347
+                if ( ! $wp_filesystem->exists( $from . $distro . 'wp-content/' . $file ) ) {
1348
+                    continue;
1349
+                }
1350
+
1351
+                if ( 'plugins' === $type ) {
1352
+                    $dest = $wp_filesystem->wp_plugins_dir();
1353
+                } elseif ( 'themes' === $type ) {
1354
+                    // Back-compat, ::wp_themes_dir() did not return trailingslash'd pre-3.2.
1355
+                    $dest = trailingslashit( $wp_filesystem->wp_themes_dir() );
1356
+                } else {
1357
+                    continue;
1358
+                }
1359
+
1360
+                if ( ! $directory ) {
1361
+                    if ( ! $development_build && $wp_filesystem->exists( $dest . $filename ) ) {
1362
+                        continue;
1363
+                    }
1364
+
1365
+                    if ( ! $wp_filesystem->copy( $from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE ) ) {
1366
+                        $result = new WP_Error( "copy_failed_for_new_bundled_$type", __( 'Could not copy file.' ), $dest . $filename );
1367
+                    }
1368
+                } else {
1369
+                    if ( ! $development_build && $wp_filesystem->is_dir( $dest . $filename ) ) {
1370
+                        continue;
1371
+                    }
1372
+
1373
+                    $wp_filesystem->mkdir( $dest . $filename, FS_CHMOD_DIR );
1374
+                    $_result = copy_dir( $from . $distro . 'wp-content/' . $file, $dest . $filename );
1375
+
1376
+                    // If a error occurs partway through this final step, keep the error flowing through, but keep process going.
1377
+                    if ( is_wp_error( $_result ) ) {
1378
+                        if ( ! is_wp_error( $result ) ) {
1379
+                            $result = new WP_Error;
1380
+                        }
1381
+
1382
+                        $result->add(
1383
+                            $_result->get_error_code() . "_$type",
1384
+                            $_result->get_error_message(),
1385
+                            substr( $_result->get_error_data(), strlen( $dest ) )
1386
+                        );
1387
+                    }
1388
+                }
1389
+            }
1390
+        } // End foreach.
1391
+    }
1392
+
1393
+    // Handle $result error from the above blocks.
1394
+    if ( is_wp_error( $result ) ) {
1395
+        $wp_filesystem->delete( $from, true );
1396
+
1397
+        return $result;
1398
+    }
1399
+
1400
+    // Remove old files.
1401
+    foreach ( $_old_files as $old_file ) {
1402
+        $old_file = $to . $old_file;
1403
+
1404
+        if ( ! $wp_filesystem->exists( $old_file ) ) {
1405
+            continue;
1406
+        }
1407
+
1408
+        // If the file isn't deleted, try writing an empty string to the file instead.
1409
+        if ( ! $wp_filesystem->delete( $old_file, true ) && $wp_filesystem->is_file( $old_file ) ) {
1410
+            $wp_filesystem->put_contents( $old_file, '' );
1411
+        }
1412
+    }
1413
+
1414
+    // Remove any Genericons example.html's from the filesystem.
1415
+    _upgrade_422_remove_genericons();
1416
+
1417
+    // Deactivate the REST API plugin if its version is 2.0 Beta 4 or lower.
1418
+    _upgrade_440_force_deactivate_incompatible_plugins();
1419
+
1420
+    // Deactivate the Gutenberg plugin if its version is 11.8 or lower.
1421
+    _upgrade_590_force_deactivate_incompatible_plugins();
1422
+
1423
+    // Upgrade DB with separate request.
1424
+    /** This filter is documented in wp-admin/includes/update-core.php */
1425
+    apply_filters( 'update_feedback', __( 'Upgrading database&#8230;' ) );
1426
+
1427
+    $db_upgrade_url = admin_url( 'upgrade.php?step=upgrade_db' );
1428
+    wp_remote_post( $db_upgrade_url, array( 'timeout' => 60 ) );
1429
+
1430
+    // Clear the cache to prevent an update_option() from saving a stale db_version to the cache.
1431
+    wp_cache_flush();
1432
+    // Not all cache back ends listen to 'flush'.
1433
+    wp_cache_delete( 'alloptions', 'options' );
1434
+
1435
+    // Remove working directory.
1436
+    $wp_filesystem->delete( $from, true );
1437
+
1438
+    // Force refresh of update information.
1439
+    if ( function_exists( 'delete_site_transient' ) ) {
1440
+        delete_site_transient( 'update_core' );
1441
+    } else {
1442
+        delete_option( 'update_core' );
1443
+    }
1444
+
1445
+    /**
1446
+     * Fires after WordPress core has been successfully updated.
1447
+     *
1448
+     * @since 3.3.0
1449
+     *
1450
+     * @param string $wp_version The current WordPress version.
1451
+     */
1452
+    do_action( '_core_updated_successfully', $wp_version );
1453
+
1454
+    // Clear the option that blocks auto-updates after failures, now that we've been successful.
1455
+    if ( function_exists( 'delete_site_option' ) ) {
1456
+        delete_site_option( 'auto_core_update_failed' );
1457
+    }
1458
+
1459
+    return $wp_version;
1460 1460
 }
1461 1461
 
1462 1462
 /**
@@ -1485,67 +1485,67 @@  discard block
 block discarded – undo
1485 1485
  * @return true|WP_Error True on success, WP_Error on failure.
1486 1486
  */
1487 1487
 function _copy_dir( $from, $to, $skip_list = array() ) {
1488
-	global $wp_filesystem;
1488
+    global $wp_filesystem;
1489 1489
 
1490
-	$dirlist = $wp_filesystem->dirlist( $from );
1490
+    $dirlist = $wp_filesystem->dirlist( $from );
1491 1491
 
1492
-	if ( false === $dirlist ) {
1493
-		return new WP_Error( 'dirlist_failed__copy_dir', __( 'Directory listing failed.' ), basename( $to ) );
1494
-	}
1492
+    if ( false === $dirlist ) {
1493
+        return new WP_Error( 'dirlist_failed__copy_dir', __( 'Directory listing failed.' ), basename( $to ) );
1494
+    }
1495 1495
 
1496
-	$from = trailingslashit( $from );
1497
-	$to   = trailingslashit( $to );
1496
+    $from = trailingslashit( $from );
1497
+    $to   = trailingslashit( $to );
1498 1498
 
1499
-	foreach ( (array) $dirlist as $filename => $fileinfo ) {
1500
-		if ( in_array( $filename, $skip_list, true ) ) {
1501
-			continue;
1502
-		}
1499
+    foreach ( (array) $dirlist as $filename => $fileinfo ) {
1500
+        if ( in_array( $filename, $skip_list, true ) ) {
1501
+            continue;
1502
+        }
1503 1503
 
1504
-		if ( 'f' === $fileinfo['type'] ) {
1505
-			if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
1506
-				// If copy failed, chmod file to 0644 and try again.
1507
-				$wp_filesystem->chmod( $to . $filename, FS_CHMOD_FILE );
1504
+        if ( 'f' === $fileinfo['type'] ) {
1505
+            if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
1506
+                // If copy failed, chmod file to 0644 and try again.
1507
+                $wp_filesystem->chmod( $to . $filename, FS_CHMOD_FILE );
1508 1508
 
1509
-				if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
1510
-					return new WP_Error( 'copy_failed__copy_dir', __( 'Could not copy file.' ), $to . $filename );
1511
-				}
1512
-			}
1509
+                if ( ! $wp_filesystem->copy( $from . $filename, $to . $filename, true, FS_CHMOD_FILE ) ) {
1510
+                    return new WP_Error( 'copy_failed__copy_dir', __( 'Could not copy file.' ), $to . $filename );
1511
+                }
1512
+            }
1513 1513
 
1514
-			/*
1514
+            /*
1515 1515
 			 * `wp_opcache_invalidate()` only exists in WordPress 5.5 or later,
1516 1516
 			 * so don't run it when upgrading from older versions.
1517 1517
 			 */
1518
-			if ( function_exists( 'wp_opcache_invalidate' ) ) {
1519
-				wp_opcache_invalidate( $to . $filename );
1520
-			}
1521
-		} elseif ( 'd' === $fileinfo['type'] ) {
1522
-			if ( ! $wp_filesystem->is_dir( $to . $filename ) ) {
1523
-				if ( ! $wp_filesystem->mkdir( $to . $filename, FS_CHMOD_DIR ) ) {
1524
-					return new WP_Error( 'mkdir_failed__copy_dir', __( 'Could not create directory.' ), $to . $filename );
1525
-				}
1526
-			}
1527
-
1528
-			/*
1518
+            if ( function_exists( 'wp_opcache_invalidate' ) ) {
1519
+                wp_opcache_invalidate( $to . $filename );
1520
+            }
1521
+        } elseif ( 'd' === $fileinfo['type'] ) {
1522
+            if ( ! $wp_filesystem->is_dir( $to . $filename ) ) {
1523
+                if ( ! $wp_filesystem->mkdir( $to . $filename, FS_CHMOD_DIR ) ) {
1524
+                    return new WP_Error( 'mkdir_failed__copy_dir', __( 'Could not create directory.' ), $to . $filename );
1525
+                }
1526
+            }
1527
+
1528
+            /*
1529 1529
 			 * Generate the $sub_skip_list for the subdirectory as a sub-set
1530 1530
 			 * of the existing $skip_list.
1531 1531
 			 */
1532
-			$sub_skip_list = array();
1532
+            $sub_skip_list = array();
1533 1533
 
1534
-			foreach ( $skip_list as $skip_item ) {
1535
-				if ( 0 === strpos( $skip_item, $filename . '/' ) ) {
1536
-					$sub_skip_list[] = preg_replace( '!^' . preg_quote( $filename, '!' ) . '/!i', '', $skip_item );
1537
-				}
1538
-			}
1534
+            foreach ( $skip_list as $skip_item ) {
1535
+                if ( 0 === strpos( $skip_item, $filename . '/' ) ) {
1536
+                    $sub_skip_list[] = preg_replace( '!^' . preg_quote( $filename, '!' ) . '/!i', '', $skip_item );
1537
+                }
1538
+            }
1539 1539
 
1540
-			$result = _copy_dir( $from . $filename, $to . $filename, $sub_skip_list );
1540
+            $result = _copy_dir( $from . $filename, $to . $filename, $sub_skip_list );
1541 1541
 
1542
-			if ( is_wp_error( $result ) ) {
1543
-				return $result;
1544
-			}
1545
-		}
1546
-	}
1542
+            if ( is_wp_error( $result ) ) {
1543
+                return $result;
1544
+            }
1545
+        }
1546
+    }
1547 1547
 
1548
-	return true;
1548
+    return true;
1549 1549
 }
1550 1550
 
1551 1551
 /**
@@ -1562,54 +1562,54 @@  discard block
 block discarded – undo
1562 1562
  * @param string $new_version
1563 1563
  */
1564 1564
 function _redirect_to_about_wordpress( $new_version ) {
1565
-	global $wp_version, $pagenow, $action;
1566
-
1567
-	if ( version_compare( $wp_version, '3.4-RC1', '>=' ) ) {
1568
-		return;
1569
-	}
1570
-
1571
-	// Ensure we only run this on the update-core.php page. The Core_Upgrader may be used in other contexts.
1572
-	if ( 'update-core.php' !== $pagenow ) {
1573
-		return;
1574
-	}
1575
-
1576
-	if ( 'do-core-upgrade' !== $action && 'do-core-reinstall' !== $action ) {
1577
-		return;
1578
-	}
1579
-
1580
-	// Load the updated default text localization domain for new strings.
1581
-	load_default_textdomain();
1582
-
1583
-	// See do_core_upgrade().
1584
-	show_message( __( 'WordPress updated successfully.' ) );
1585
-
1586
-	// self_admin_url() won't exist when upgrading from <= 3.0, so relative URLs are intentional.
1587
-	show_message(
1588
-		'<span class="hide-if-no-js">' . sprintf(
1589
-			/* translators: 1: WordPress version, 2: URL to About screen. */
1590
-			__( 'Welcome to WordPress %1$s. You will be redirected to the About WordPress screen. If not, click <a href="%2$s">here</a>.' ),
1591
-			$new_version,
1592
-			'about.php?updated'
1593
-		) . '</span>'
1594
-	);
1595
-	show_message(
1596
-		'<span class="hide-if-js">' . sprintf(
1597
-			/* translators: 1: WordPress version, 2: URL to About screen. */
1598
-			__( 'Welcome to WordPress %1$s. <a href="%2$s">Learn more</a>.' ),
1599
-			$new_version,
1600
-			'about.php?updated'
1601
-		) . '</span>'
1602
-	);
1603
-	echo '</div>';
1604
-	?>
1565
+    global $wp_version, $pagenow, $action;
1566
+
1567
+    if ( version_compare( $wp_version, '3.4-RC1', '>=' ) ) {
1568
+        return;
1569
+    }
1570
+
1571
+    // Ensure we only run this on the update-core.php page. The Core_Upgrader may be used in other contexts.
1572
+    if ( 'update-core.php' !== $pagenow ) {
1573
+        return;
1574
+    }
1575
+
1576
+    if ( 'do-core-upgrade' !== $action && 'do-core-reinstall' !== $action ) {
1577
+        return;
1578
+    }
1579
+
1580
+    // Load the updated default text localization domain for new strings.
1581
+    load_default_textdomain();
1582
+
1583
+    // See do_core_upgrade().
1584
+    show_message( __( 'WordPress updated successfully.' ) );
1585
+
1586
+    // self_admin_url() won't exist when upgrading from <= 3.0, so relative URLs are intentional.
1587
+    show_message(
1588
+        '<span class="hide-if-no-js">' . sprintf(
1589
+            /* translators: 1: WordPress version, 2: URL to About screen. */
1590
+            __( 'Welcome to WordPress %1$s. You will be redirected to the About WordPress screen. If not, click <a href="%2$s">here</a>.' ),
1591
+            $new_version,
1592
+            'about.php?updated'
1593
+        ) . '</span>'
1594
+    );
1595
+    show_message(
1596
+        '<span class="hide-if-js">' . sprintf(
1597
+            /* translators: 1: WordPress version, 2: URL to About screen. */
1598
+            __( 'Welcome to WordPress %1$s. <a href="%2$s">Learn more</a>.' ),
1599
+            $new_version,
1600
+            'about.php?updated'
1601
+        ) . '</span>'
1602
+    );
1603
+    echo '</div>';
1604
+    ?>
1605 1605
 <script type="text/javascript">
1606 1606
 window.location = 'about.php?updated';
1607 1607
 </script>
1608 1608
 	<?php
1609 1609
 
1610
-	// Include admin-footer.php and exit.
1611
-	require_once ABSPATH . 'wp-admin/admin-footer.php';
1612
-	exit;
1610
+    // Include admin-footer.php and exit.
1611
+    require_once ABSPATH . 'wp-admin/admin-footer.php';
1612
+    exit;
1613 1613
 }
1614 1614
 
1615 1615
 /**
@@ -1621,39 +1621,39 @@  discard block
 block discarded – undo
1621 1621
  * @global WP_Filesystem_Base $wp_filesystem
1622 1622
  */
1623 1623
 function _upgrade_422_remove_genericons() {
1624
-	global $wp_theme_directories, $wp_filesystem;
1624
+    global $wp_theme_directories, $wp_filesystem;
1625 1625
 
1626
-	// A list of the affected files using the filesystem absolute paths.
1627
-	$affected_files = array();
1626
+    // A list of the affected files using the filesystem absolute paths.
1627
+    $affected_files = array();
1628 1628
 
1629
-	// Themes.
1630
-	foreach ( $wp_theme_directories as $directory ) {
1631
-		$affected_theme_files = _upgrade_422_find_genericons_files_in_folder( $directory );
1632
-		$affected_files       = array_merge( $affected_files, $affected_theme_files );
1633
-	}
1629
+    // Themes.
1630
+    foreach ( $wp_theme_directories as $directory ) {
1631
+        $affected_theme_files = _upgrade_422_find_genericons_files_in_folder( $directory );
1632
+        $affected_files       = array_merge( $affected_files, $affected_theme_files );
1633
+    }
1634 1634
 
1635
-	// Plugins.
1636
-	$affected_plugin_files = _upgrade_422_find_genericons_files_in_folder( WP_PLUGIN_DIR );
1637
-	$affected_files        = array_merge( $affected_files, $affected_plugin_files );
1635
+    // Plugins.
1636
+    $affected_plugin_files = _upgrade_422_find_genericons_files_in_folder( WP_PLUGIN_DIR );
1637
+    $affected_files        = array_merge( $affected_files, $affected_plugin_files );
1638 1638
 
1639
-	foreach ( $affected_files as $file ) {
1640
-		$gen_dir = $wp_filesystem->find_folder( trailingslashit( dirname( $file ) ) );
1639
+    foreach ( $affected_files as $file ) {
1640
+        $gen_dir = $wp_filesystem->find_folder( trailingslashit( dirname( $file ) ) );
1641 1641
 
1642
-		if ( empty( $gen_dir ) ) {
1643
-			continue;
1644
-		}
1642
+        if ( empty( $gen_dir ) ) {
1643
+            continue;
1644
+        }
1645 1645
 
1646
-		// The path when the file is accessed via WP_Filesystem may differ in the case of FTP.
1647
-		$remote_file = $gen_dir . basename( $file );
1646
+        // The path when the file is accessed via WP_Filesystem may differ in the case of FTP.
1647
+        $remote_file = $gen_dir . basename( $file );
1648 1648
 
1649
-		if ( ! $wp_filesystem->exists( $remote_file ) ) {
1650
-			continue;
1651
-		}
1649
+        if ( ! $wp_filesystem->exists( $remote_file ) ) {
1650
+            continue;
1651
+        }
1652 1652
 
1653
-		if ( ! $wp_filesystem->delete( $remote_file, false, 'f' ) ) {
1654
-			$wp_filesystem->put_contents( $remote_file, '' );
1655
-		}
1656
-	}
1653
+        if ( ! $wp_filesystem->delete( $remote_file, false, 'f' ) ) {
1654
+            $wp_filesystem->put_contents( $remote_file, '' );
1655
+        }
1656
+    }
1657 1657
 }
1658 1658
 
1659 1659
 /**
@@ -1666,31 +1666,31 @@  discard block
 block discarded – undo
1666 1666
  * @return array
1667 1667
  */
1668 1668
 function _upgrade_422_find_genericons_files_in_folder( $directory ) {
1669
-	$directory = trailingslashit( $directory );
1670
-	$files     = array();
1671
-
1672
-	if ( file_exists( "{$directory}example.html" )
1673
-		&& false !== strpos( file_get_contents( "{$directory}example.html" ), '<title>Genericons</title>' )
1674
-	) {
1675
-		$files[] = "{$directory}example.html";
1676
-	}
1677
-
1678
-	$dirs = glob( $directory . '*', GLOB_ONLYDIR );
1679
-	$dirs = array_filter(
1680
-		$dirs,
1681
-		static function( $dir ) {
1682
-			// Skip any node_modules directories.
1683
-			return false === strpos( $dir, 'node_modules' );
1684
-		}
1685
-	);
1686
-
1687
-	if ( $dirs ) {
1688
-		foreach ( $dirs as $dir ) {
1689
-			$files = array_merge( $files, _upgrade_422_find_genericons_files_in_folder( $dir ) );
1690
-		}
1691
-	}
1692
-
1693
-	return $files;
1669
+    $directory = trailingslashit( $directory );
1670
+    $files     = array();
1671
+
1672
+    if ( file_exists( "{$directory}example.html" )
1673
+        && false !== strpos( file_get_contents( "{$directory}example.html" ), '<title>Genericons</title>' )
1674
+    ) {
1675
+        $files[] = "{$directory}example.html";
1676
+    }
1677
+
1678
+    $dirs = glob( $directory . '*', GLOB_ONLYDIR );
1679
+    $dirs = array_filter(
1680
+        $dirs,
1681
+        static function( $dir ) {
1682
+            // Skip any node_modules directories.
1683
+            return false === strpos( $dir, 'node_modules' );
1684
+        }
1685
+    );
1686
+
1687
+    if ( $dirs ) {
1688
+        foreach ( $dirs as $dir ) {
1689
+            $files = array_merge( $files, _upgrade_422_find_genericons_files_in_folder( $dir ) );
1690
+        }
1691
+    }
1692
+
1693
+    return $files;
1694 1694
 }
1695 1695
 
1696 1696
 /**
@@ -1698,9 +1698,9 @@  discard block
 block discarded – undo
1698 1698
  * @since 4.4.0
1699 1699
  */
1700 1700
 function _upgrade_440_force_deactivate_incompatible_plugins() {
1701
-	if ( defined( 'REST_API_VERSION' ) && version_compare( REST_API_VERSION, '2.0-beta4', '<=' ) ) {
1702
-		deactivate_plugins( array( 'rest-api/plugin.php' ), true );
1703
-	}
1701
+    if ( defined( 'REST_API_VERSION' ) && version_compare( REST_API_VERSION, '2.0-beta4', '<=' ) ) {
1702
+        deactivate_plugins( array( 'rest-api/plugin.php' ), true );
1703
+    }
1704 1704
 }
1705 1705
 
1706 1706
 /**
@@ -1709,21 +1709,21 @@  discard block
 block discarded – undo
1709 1709
  * @since 5.9.0
1710 1710
  */
1711 1711
 function _upgrade_590_force_deactivate_incompatible_plugins() {
1712
-	if ( defined( 'GUTENBERG_VERSION' ) && version_compare( GUTENBERG_VERSION, '11.9', '<' ) ) {
1713
-		$deactivated_gutenberg['gutenberg'] = array(
1714
-			'plugin_name'         => 'Gutenberg',
1715
-			'version_deactivated' => GUTENBERG_VERSION,
1716
-			'version_compatible'  => '11.9',
1717
-		);
1718
-		if ( is_plugin_active_for_network( 'gutenberg/gutenberg.php' ) ) {
1719
-			$deactivated_plugins = get_site_option( 'wp_force_deactivated_plugins', array() );
1720
-			$deactivated_plugins = array_merge( $deactivated_plugins, $deactivated_gutenberg );
1721
-			update_site_option( 'wp_force_deactivated_plugins', $deactivated_plugins );
1722
-		} else {
1723
-			$deactivated_plugins = get_option( 'wp_force_deactivated_plugins', array() );
1724
-			$deactivated_plugins = array_merge( $deactivated_plugins, $deactivated_gutenberg );
1725
-			update_option( 'wp_force_deactivated_plugins', $deactivated_plugins );
1726
-		}
1727
-		deactivate_plugins( array( 'gutenberg/gutenberg.php' ), true );
1728
-	}
1712
+    if ( defined( 'GUTENBERG_VERSION' ) && version_compare( GUTENBERG_VERSION, '11.9', '<' ) ) {
1713
+        $deactivated_gutenberg['gutenberg'] = array(
1714
+            'plugin_name'         => 'Gutenberg',
1715
+            'version_deactivated' => GUTENBERG_VERSION,
1716
+            'version_compatible'  => '11.9',
1717
+        );
1718
+        if ( is_plugin_active_for_network( 'gutenberg/gutenberg.php' ) ) {
1719
+            $deactivated_plugins = get_site_option( 'wp_force_deactivated_plugins', array() );
1720
+            $deactivated_plugins = array_merge( $deactivated_plugins, $deactivated_gutenberg );
1721
+            update_site_option( 'wp_force_deactivated_plugins', $deactivated_plugins );
1722
+        } else {
1723
+            $deactivated_plugins = get_option( 'wp_force_deactivated_plugins', array() );
1724
+            $deactivated_plugins = array_merge( $deactivated_plugins, $deactivated_gutenberg );
1725
+            update_option( 'wp_force_deactivated_plugins', $deactivated_plugins );
1726
+        }
1727
+        deactivate_plugins( array( 'gutenberg/gutenberg.php' ), true );
1728
+    }
1729 1729
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/class-wp-community-events.php 1 patch
Indentation   +472 added lines, -472 removed lines patch added patch discarded remove patch
@@ -15,127 +15,127 @@  discard block
 block discarded – undo
15 15
  * @since 4.8.0
16 16
  */
17 17
 class WP_Community_Events {
18
-	/**
19
-	 * ID for a WordPress user account.
20
-	 *
21
-	 * @since 4.8.0
22
-	 *
23
-	 * @var int
24
-	 */
25
-	protected $user_id = 0;
26
-
27
-	/**
28
-	 * Stores location data for the user.
29
-	 *
30
-	 * @since 4.8.0
31
-	 *
32
-	 * @var false|array
33
-	 */
34
-	protected $user_location = false;
35
-
36
-	/**
37
-	 * Constructor for WP_Community_Events.
38
-	 *
39
-	 * @since 4.8.0
40
-	 *
41
-	 * @param int        $user_id       WP user ID.
42
-	 * @param false|array $user_location {
43
-	 *     Stored location data for the user. false to pass no location.
44
-	 *
45
-	 *     @type string $description The name of the location
46
-	 *     @type string $latitude    The latitude in decimal degrees notation, without the degree
47
-	 *                               symbol. e.g.: 47.615200.
48
-	 *     @type string $longitude   The longitude in decimal degrees notation, without the degree
49
-	 *                               symbol. e.g.: -122.341100.
50
-	 *     @type string $country     The ISO 3166-1 alpha-2 country code. e.g.: BR
51
-	 * }
52
-	 */
53
-	public function __construct( $user_id, $user_location = false ) {
54
-		$this->user_id       = absint( $user_id );
55
-		$this->user_location = $user_location;
56
-	}
57
-
58
-	/**
59
-	 * Gets data about events near a particular location.
60
-	 *
61
-	 * Cached events will be immediately returned if the `user_location` property
62
-	 * is set for the current user, and cached events exist for that location.
63
-	 *
64
-	 * Otherwise, this method sends a request to the w.org Events API with location
65
-	 * data. The API will send back a recognized location based on the data, along
66
-	 * with nearby events.
67
-	 *
68
-	 * The browser's request for events is proxied with this method, rather
69
-	 * than having the browser make the request directly to api.wordpress.org,
70
-	 * because it allows results to be cached server-side and shared with other
71
-	 * users and sites in the network. This makes the process more efficient,
72
-	 * since increasing the number of visits that get cached data means users
73
-	 * don't have to wait as often; if the user's browser made the request
74
-	 * directly, it would also need to make a second request to WP in order to
75
-	 * pass the data for caching. Having WP make the request also introduces
76
-	 * the opportunity to anonymize the IP before sending it to w.org, which
77
-	 * mitigates possible privacy concerns.
78
-	 *
79
-	 * @since 4.8.0
80
-	 * @since 5.5.2 Response no longer contains formatted date field. They're added
81
-	 *              in `wp.communityEvents.populateDynamicEventFields()` now.
82
-	 *
83
-	 * @param string $location_search Optional. City name to help determine the location.
84
-	 *                                e.g., "Seattle". Default empty string.
85
-	 * @param string $timezone        Optional. Timezone to help determine the location.
86
-	 *                                Default empty string.
87
-	 * @return array|WP_Error A WP_Error on failure; an array with location and events on
88
-	 *                        success.
89
-	 */
90
-	public function get_events( $location_search = '', $timezone = '' ) {
91
-		$cached_events = $this->get_cached_events();
92
-
93
-		if ( ! $location_search && $cached_events ) {
94
-			return $cached_events;
95
-		}
96
-
97
-		// Include an unmodified $wp_version.
98
-		require ABSPATH . WPINC . '/version.php';
99
-
100
-		$api_url                    = 'http://api.wordpress.org/events/1.0/';
101
-		$request_args               = $this->get_request_args( $location_search, $timezone );
102
-		$request_args['user-agent'] = 'WordPress/' . $wp_version . '; ' . home_url( '/' );
103
-
104
-		if ( wp_http_supports( array( 'ssl' ) ) ) {
105
-			$api_url = set_url_scheme( $api_url, 'https' );
106
-		}
107
-
108
-		$response       = wp_remote_get( $api_url, $request_args );
109
-		$response_code  = wp_remote_retrieve_response_code( $response );
110
-		$response_body  = json_decode( wp_remote_retrieve_body( $response ), true );
111
-		$response_error = null;
112
-
113
-		if ( is_wp_error( $response ) ) {
114
-			$response_error = $response;
115
-		} elseif ( 200 !== $response_code ) {
116
-			$response_error = new WP_Error(
117
-				'api-error',
118
-				/* translators: %d: Numeric HTTP status code, e.g. 400, 403, 500, 504, etc. */
119
-				sprintf( __( 'Invalid API response code (%d).' ), $response_code )
120
-			);
121
-		} elseif ( ! isset( $response_body['location'], $response_body['events'] ) ) {
122
-			$response_error = new WP_Error(
123
-				'api-invalid-response',
124
-				isset( $response_body['error'] ) ? $response_body['error'] : __( 'Unknown API error.' )
125
-			);
126
-		}
127
-
128
-		if ( is_wp_error( $response_error ) ) {
129
-			return $response_error;
130
-		} else {
131
-			$expiration = false;
132
-
133
-			if ( isset( $response_body['ttl'] ) ) {
134
-				$expiration = $response_body['ttl'];
135
-				unset( $response_body['ttl'] );
136
-			}
137
-
138
-			/*
18
+    /**
19
+     * ID for a WordPress user account.
20
+     *
21
+     * @since 4.8.0
22
+     *
23
+     * @var int
24
+     */
25
+    protected $user_id = 0;
26
+
27
+    /**
28
+     * Stores location data for the user.
29
+     *
30
+     * @since 4.8.0
31
+     *
32
+     * @var false|array
33
+     */
34
+    protected $user_location = false;
35
+
36
+    /**
37
+     * Constructor for WP_Community_Events.
38
+     *
39
+     * @since 4.8.0
40
+     *
41
+     * @param int        $user_id       WP user ID.
42
+     * @param false|array $user_location {
43
+     *     Stored location data for the user. false to pass no location.
44
+     *
45
+     *     @type string $description The name of the location
46
+     *     @type string $latitude    The latitude in decimal degrees notation, without the degree
47
+     *                               symbol. e.g.: 47.615200.
48
+     *     @type string $longitude   The longitude in decimal degrees notation, without the degree
49
+     *                               symbol. e.g.: -122.341100.
50
+     *     @type string $country     The ISO 3166-1 alpha-2 country code. e.g.: BR
51
+     * }
52
+     */
53
+    public function __construct( $user_id, $user_location = false ) {
54
+        $this->user_id       = absint( $user_id );
55
+        $this->user_location = $user_location;
56
+    }
57
+
58
+    /**
59
+     * Gets data about events near a particular location.
60
+     *
61
+     * Cached events will be immediately returned if the `user_location` property
62
+     * is set for the current user, and cached events exist for that location.
63
+     *
64
+     * Otherwise, this method sends a request to the w.org Events API with location
65
+     * data. The API will send back a recognized location based on the data, along
66
+     * with nearby events.
67
+     *
68
+     * The browser's request for events is proxied with this method, rather
69
+     * than having the browser make the request directly to api.wordpress.org,
70
+     * because it allows results to be cached server-side and shared with other
71
+     * users and sites in the network. This makes the process more efficient,
72
+     * since increasing the number of visits that get cached data means users
73
+     * don't have to wait as often; if the user's browser made the request
74
+     * directly, it would also need to make a second request to WP in order to
75
+     * pass the data for caching. Having WP make the request also introduces
76
+     * the opportunity to anonymize the IP before sending it to w.org, which
77
+     * mitigates possible privacy concerns.
78
+     *
79
+     * @since 4.8.0
80
+     * @since 5.5.2 Response no longer contains formatted date field. They're added
81
+     *              in `wp.communityEvents.populateDynamicEventFields()` now.
82
+     *
83
+     * @param string $location_search Optional. City name to help determine the location.
84
+     *                                e.g., "Seattle". Default empty string.
85
+     * @param string $timezone        Optional. Timezone to help determine the location.
86
+     *                                Default empty string.
87
+     * @return array|WP_Error A WP_Error on failure; an array with location and events on
88
+     *                        success.
89
+     */
90
+    public function get_events( $location_search = '', $timezone = '' ) {
91
+        $cached_events = $this->get_cached_events();
92
+
93
+        if ( ! $location_search && $cached_events ) {
94
+            return $cached_events;
95
+        }
96
+
97
+        // Include an unmodified $wp_version.
98
+        require ABSPATH . WPINC . '/version.php';
99
+
100
+        $api_url                    = 'http://api.wordpress.org/events/1.0/';
101
+        $request_args               = $this->get_request_args( $location_search, $timezone );
102
+        $request_args['user-agent'] = 'WordPress/' . $wp_version . '; ' . home_url( '/' );
103
+
104
+        if ( wp_http_supports( array( 'ssl' ) ) ) {
105
+            $api_url = set_url_scheme( $api_url, 'https' );
106
+        }
107
+
108
+        $response       = wp_remote_get( $api_url, $request_args );
109
+        $response_code  = wp_remote_retrieve_response_code( $response );
110
+        $response_body  = json_decode( wp_remote_retrieve_body( $response ), true );
111
+        $response_error = null;
112
+
113
+        if ( is_wp_error( $response ) ) {
114
+            $response_error = $response;
115
+        } elseif ( 200 !== $response_code ) {
116
+            $response_error = new WP_Error(
117
+                'api-error',
118
+                /* translators: %d: Numeric HTTP status code, e.g. 400, 403, 500, 504, etc. */
119
+                sprintf( __( 'Invalid API response code (%d).' ), $response_code )
120
+            );
121
+        } elseif ( ! isset( $response_body['location'], $response_body['events'] ) ) {
122
+            $response_error = new WP_Error(
123
+                'api-invalid-response',
124
+                isset( $response_body['error'] ) ? $response_body['error'] : __( 'Unknown API error.' )
125
+            );
126
+        }
127
+
128
+        if ( is_wp_error( $response_error ) ) {
129
+            return $response_error;
130
+        } else {
131
+            $expiration = false;
132
+
133
+            if ( isset( $response_body['ttl'] ) ) {
134
+                $expiration = $response_body['ttl'];
135
+                unset( $response_body['ttl'] );
136
+            }
137
+
138
+            /*
139 139
 			 * The IP in the response is usually the same as the one that was sent
140 140
 			 * in the request, but in some cases it is different. In those cases,
141 141
 			 * it's important to reset it back to the IP from the request.
@@ -147,379 +147,379 @@  discard block
 block discarded – undo
147 147
 			 * would be generated based on the public IP when saving the cache, but generated
148 148
 			 * based on the private IP when retrieving the cache.
149 149
 			 */
150
-			if ( ! empty( $response_body['location']['ip'] ) ) {
151
-				$response_body['location']['ip'] = $request_args['body']['ip'];
152
-			}
150
+            if ( ! empty( $response_body['location']['ip'] ) ) {
151
+                $response_body['location']['ip'] = $request_args['body']['ip'];
152
+            }
153 153
 
154
-			/*
154
+            /*
155 155
 			 * The API doesn't return a description for latitude/longitude requests,
156 156
 			 * but the description is already saved in the user location, so that
157 157
 			 * one can be used instead.
158 158
 			 */
159
-			if ( $this->coordinates_match( $request_args['body'], $response_body['location'] ) && empty( $response_body['location']['description'] ) ) {
160
-				$response_body['location']['description'] = $this->user_location['description'];
161
-			}
159
+            if ( $this->coordinates_match( $request_args['body'], $response_body['location'] ) && empty( $response_body['location']['description'] ) ) {
160
+                $response_body['location']['description'] = $this->user_location['description'];
161
+            }
162 162
 
163
-			/*
163
+            /*
164 164
 			 * Store the raw response, because events will expire before the cache does.
165 165
 			 * The response will need to be processed every page load.
166 166
 			 */
167
-			$this->cache_events( $response_body, $expiration );
168
-
169
-			$response_body['events'] = $this->trim_events( $response_body['events'] );
170
-
171
-			return $response_body;
172
-		}
173
-	}
174
-
175
-	/**
176
-	 * Builds an array of args to use in an HTTP request to the w.org Events API.
177
-	 *
178
-	 * @since 4.8.0
179
-	 *
180
-	 * @param string $search   Optional. City search string. Default empty string.
181
-	 * @param string $timezone Optional. Timezone string. Default empty string.
182
-	 * @return array The request args.
183
-	 */
184
-	protected function get_request_args( $search = '', $timezone = '' ) {
185
-		$args = array(
186
-			'number' => 5, // Get more than three in case some get trimmed out.
187
-			'ip'     => self::get_unsafe_client_ip(),
188
-		);
189
-
190
-		/*
167
+            $this->cache_events( $response_body, $expiration );
168
+
169
+            $response_body['events'] = $this->trim_events( $response_body['events'] );
170
+
171
+            return $response_body;
172
+        }
173
+    }
174
+
175
+    /**
176
+     * Builds an array of args to use in an HTTP request to the w.org Events API.
177
+     *
178
+     * @since 4.8.0
179
+     *
180
+     * @param string $search   Optional. City search string. Default empty string.
181
+     * @param string $timezone Optional. Timezone string. Default empty string.
182
+     * @return array The request args.
183
+     */
184
+    protected function get_request_args( $search = '', $timezone = '' ) {
185
+        $args = array(
186
+            'number' => 5, // Get more than three in case some get trimmed out.
187
+            'ip'     => self::get_unsafe_client_ip(),
188
+        );
189
+
190
+        /*
191 191
 		 * Include the minimal set of necessary arguments, in order to increase the
192 192
 		 * chances of a cache-hit on the API side.
193 193
 		 */
194
-		if ( empty( $search ) && isset( $this->user_location['latitude'], $this->user_location['longitude'] ) ) {
195
-			$args['latitude']  = $this->user_location['latitude'];
196
-			$args['longitude'] = $this->user_location['longitude'];
197
-		} else {
198
-			$args['locale'] = get_user_locale( $this->user_id );
199
-
200
-			if ( $timezone ) {
201
-				$args['timezone'] = $timezone;
202
-			}
203
-
204
-			if ( $search ) {
205
-				$args['location'] = $search;
206
-			}
207
-		}
208
-
209
-		// Wrap the args in an array compatible with the second parameter of `wp_remote_get()`.
210
-		return array(
211
-			'body' => $args,
212
-		);
213
-	}
214
-
215
-	/**
216
-	 * Determines the user's actual IP address and attempts to partially
217
-	 * anonymize an IP address by converting it to a network ID.
218
-	 *
219
-	 * Geolocating the network ID usually returns a similar location as the
220
-	 * actual IP, but provides some privacy for the user.
221
-	 *
222
-	 * $_SERVER['REMOTE_ADDR'] cannot be used in all cases, such as when the user
223
-	 * is making their request through a proxy, or when the web server is behind
224
-	 * a proxy. In those cases, $_SERVER['REMOTE_ADDR'] is set to the proxy address rather
225
-	 * than the user's actual address.
226
-	 *
227
-	 * Modified from https://stackoverflow.com/a/2031935/450127, MIT license.
228
-	 * Modified from https://github.com/geertw/php-ip-anonymizer, MIT license.
229
-	 *
230
-	 * SECURITY WARNING: This function is _NOT_ intended to be used in
231
-	 * circumstances where the authenticity of the IP address matters. This does
232
-	 * _NOT_ guarantee that the returned address is valid or accurate, and it can
233
-	 * be easily spoofed.
234
-	 *
235
-	 * @since 4.8.0
236
-	 *
237
-	 * @return string|false The anonymized address on success; the given address
238
-	 *                      or false on failure.
239
-	 */
240
-	public static function get_unsafe_client_ip() {
241
-		$client_ip = false;
242
-
243
-		// In order of preference, with the best ones for this purpose first.
244
-		$address_headers = array(
245
-			'HTTP_CLIENT_IP',
246
-			'HTTP_X_FORWARDED_FOR',
247
-			'HTTP_X_FORWARDED',
248
-			'HTTP_X_CLUSTER_CLIENT_IP',
249
-			'HTTP_FORWARDED_FOR',
250
-			'HTTP_FORWARDED',
251
-			'REMOTE_ADDR',
252
-		);
253
-
254
-		foreach ( $address_headers as $header ) {
255
-			if ( array_key_exists( $header, $_SERVER ) ) {
256
-				/*
194
+        if ( empty( $search ) && isset( $this->user_location['latitude'], $this->user_location['longitude'] ) ) {
195
+            $args['latitude']  = $this->user_location['latitude'];
196
+            $args['longitude'] = $this->user_location['longitude'];
197
+        } else {
198
+            $args['locale'] = get_user_locale( $this->user_id );
199
+
200
+            if ( $timezone ) {
201
+                $args['timezone'] = $timezone;
202
+            }
203
+
204
+            if ( $search ) {
205
+                $args['location'] = $search;
206
+            }
207
+        }
208
+
209
+        // Wrap the args in an array compatible with the second parameter of `wp_remote_get()`.
210
+        return array(
211
+            'body' => $args,
212
+        );
213
+    }
214
+
215
+    /**
216
+     * Determines the user's actual IP address and attempts to partially
217
+     * anonymize an IP address by converting it to a network ID.
218
+     *
219
+     * Geolocating the network ID usually returns a similar location as the
220
+     * actual IP, but provides some privacy for the user.
221
+     *
222
+     * $_SERVER['REMOTE_ADDR'] cannot be used in all cases, such as when the user
223
+     * is making their request through a proxy, or when the web server is behind
224
+     * a proxy. In those cases, $_SERVER['REMOTE_ADDR'] is set to the proxy address rather
225
+     * than the user's actual address.
226
+     *
227
+     * Modified from https://stackoverflow.com/a/2031935/450127, MIT license.
228
+     * Modified from https://github.com/geertw/php-ip-anonymizer, MIT license.
229
+     *
230
+     * SECURITY WARNING: This function is _NOT_ intended to be used in
231
+     * circumstances where the authenticity of the IP address matters. This does
232
+     * _NOT_ guarantee that the returned address is valid or accurate, and it can
233
+     * be easily spoofed.
234
+     *
235
+     * @since 4.8.0
236
+     *
237
+     * @return string|false The anonymized address on success; the given address
238
+     *                      or false on failure.
239
+     */
240
+    public static function get_unsafe_client_ip() {
241
+        $client_ip = false;
242
+
243
+        // In order of preference, with the best ones for this purpose first.
244
+        $address_headers = array(
245
+            'HTTP_CLIENT_IP',
246
+            'HTTP_X_FORWARDED_FOR',
247
+            'HTTP_X_FORWARDED',
248
+            'HTTP_X_CLUSTER_CLIENT_IP',
249
+            'HTTP_FORWARDED_FOR',
250
+            'HTTP_FORWARDED',
251
+            'REMOTE_ADDR',
252
+        );
253
+
254
+        foreach ( $address_headers as $header ) {
255
+            if ( array_key_exists( $header, $_SERVER ) ) {
256
+                /*
257 257
 				 * HTTP_X_FORWARDED_FOR can contain a chain of comma-separated
258 258
 				 * addresses. The first one is the original client. It can't be
259 259
 				 * trusted for authenticity, but we don't need to for this purpose.
260 260
 				 */
261
-				$address_chain = explode( ',', $_SERVER[ $header ] );
262
-				$client_ip     = trim( $address_chain[0] );
263
-
264
-				break;
265
-			}
266
-		}
267
-
268
-		if ( ! $client_ip ) {
269
-			return false;
270
-		}
271
-
272
-		$anon_ip = wp_privacy_anonymize_ip( $client_ip, true );
273
-
274
-		if ( '0.0.0.0' === $anon_ip || '::' === $anon_ip ) {
275
-			return false;
276
-		}
277
-
278
-		return $anon_ip;
279
-	}
280
-
281
-	/**
282
-	 * Test if two pairs of latitude/longitude coordinates match each other.
283
-	 *
284
-	 * @since 4.8.0
285
-	 *
286
-	 * @param array $a The first pair, with indexes 'latitude' and 'longitude'.
287
-	 * @param array $b The second pair, with indexes 'latitude' and 'longitude'.
288
-	 * @return bool True if they match, false if they don't.
289
-	 */
290
-	protected function coordinates_match( $a, $b ) {
291
-		if ( ! isset( $a['latitude'], $a['longitude'], $b['latitude'], $b['longitude'] ) ) {
292
-			return false;
293
-		}
294
-
295
-		return $a['latitude'] === $b['latitude'] && $a['longitude'] === $b['longitude'];
296
-	}
297
-
298
-	/**
299
-	 * Generates a transient key based on user location.
300
-	 *
301
-	 * This could be reduced to a one-liner in the calling functions, but it's
302
-	 * intentionally a separate function because it's called from multiple
303
-	 * functions, and having it abstracted keeps the logic consistent and DRY,
304
-	 * which is less prone to errors.
305
-	 *
306
-	 * @since 4.8.0
307
-	 *
308
-	 * @param array $location Should contain 'latitude' and 'longitude' indexes.
309
-	 * @return string|false Transient key on success, false on failure.
310
-	 */
311
-	protected function get_events_transient_key( $location ) {
312
-		$key = false;
313
-
314
-		if ( isset( $location['ip'] ) ) {
315
-			$key = 'community-events-' . md5( $location['ip'] );
316
-		} elseif ( isset( $location['latitude'], $location['longitude'] ) ) {
317
-			$key = 'community-events-' . md5( $location['latitude'] . $location['longitude'] );
318
-		}
319
-
320
-		return $key;
321
-	}
322
-
323
-	/**
324
-	 * Caches an array of events data from the Events API.
325
-	 *
326
-	 * @since 4.8.0
327
-	 *
328
-	 * @param array     $events     Response body from the API request.
329
-	 * @param int|false $expiration Optional. Amount of time to cache the events. Defaults to false.
330
-	 * @return bool true if events were cached; false if not.
331
-	 */
332
-	protected function cache_events( $events, $expiration = false ) {
333
-		$set              = false;
334
-		$transient_key    = $this->get_events_transient_key( $events['location'] );
335
-		$cache_expiration = $expiration ? absint( $expiration ) : HOUR_IN_SECONDS * 12;
336
-
337
-		if ( $transient_key ) {
338
-			$set = set_site_transient( $transient_key, $events, $cache_expiration );
339
-		}
340
-
341
-		return $set;
342
-	}
343
-
344
-	/**
345
-	 * Gets cached events.
346
-	 *
347
-	 * @since 4.8.0
348
-	 * @since 5.5.2 Response no longer contains formatted date field. They're added
349
-	 *              in `wp.communityEvents.populateDynamicEventFields()` now.
350
-	 *
351
-	 * @return array|false An array containing `location` and `events` items
352
-	 *                     on success, false on failure.
353
-	 */
354
-	public function get_cached_events() {
355
-		$cached_response = get_site_transient( $this->get_events_transient_key( $this->user_location ) );
356
-
357
-		if ( isset( $cached_response['events'] ) ) {
358
-			$cached_response['events'] = $this->trim_events( $cached_response['events'] );
359
-		}
360
-
361
-		return $cached_response;
362
-	}
363
-
364
-	/**
365
-	 * Adds formatted date and time items for each event in an API response.
366
-	 *
367
-	 * This has to be called after the data is pulled from the cache, because
368
-	 * the cached events are shared by all users. If it was called before storing
369
-	 * the cache, then all users would see the events in the localized data/time
370
-	 * of the user who triggered the cache refresh, rather than their own.
371
-	 *
372
-	 * @since 4.8.0
373
-	 * @deprecated 5.6.0 No longer used in core.
374
-	 *
375
-	 * @param array $response_body The response which contains the events.
376
-	 * @return array The response with dates and times formatted.
377
-	 */
378
-	protected function format_event_data_time( $response_body ) {
379
-		_deprecated_function(
380
-			__METHOD__,
381
-			'5.5.2',
382
-			'This is no longer used by core, and only kept for backward compatibility.'
383
-		);
384
-
385
-		if ( isset( $response_body['events'] ) ) {
386
-			foreach ( $response_body['events'] as $key => $event ) {
387
-				$timestamp = strtotime( $event['date'] );
388
-
389
-				/*
261
+                $address_chain = explode( ',', $_SERVER[ $header ] );
262
+                $client_ip     = trim( $address_chain[0] );
263
+
264
+                break;
265
+            }
266
+        }
267
+
268
+        if ( ! $client_ip ) {
269
+            return false;
270
+        }
271
+
272
+        $anon_ip = wp_privacy_anonymize_ip( $client_ip, true );
273
+
274
+        if ( '0.0.0.0' === $anon_ip || '::' === $anon_ip ) {
275
+            return false;
276
+        }
277
+
278
+        return $anon_ip;
279
+    }
280
+
281
+    /**
282
+     * Test if two pairs of latitude/longitude coordinates match each other.
283
+     *
284
+     * @since 4.8.0
285
+     *
286
+     * @param array $a The first pair, with indexes 'latitude' and 'longitude'.
287
+     * @param array $b The second pair, with indexes 'latitude' and 'longitude'.
288
+     * @return bool True if they match, false if they don't.
289
+     */
290
+    protected function coordinates_match( $a, $b ) {
291
+        if ( ! isset( $a['latitude'], $a['longitude'], $b['latitude'], $b['longitude'] ) ) {
292
+            return false;
293
+        }
294
+
295
+        return $a['latitude'] === $b['latitude'] && $a['longitude'] === $b['longitude'];
296
+    }
297
+
298
+    /**
299
+     * Generates a transient key based on user location.
300
+     *
301
+     * This could be reduced to a one-liner in the calling functions, but it's
302
+     * intentionally a separate function because it's called from multiple
303
+     * functions, and having it abstracted keeps the logic consistent and DRY,
304
+     * which is less prone to errors.
305
+     *
306
+     * @since 4.8.0
307
+     *
308
+     * @param array $location Should contain 'latitude' and 'longitude' indexes.
309
+     * @return string|false Transient key on success, false on failure.
310
+     */
311
+    protected function get_events_transient_key( $location ) {
312
+        $key = false;
313
+
314
+        if ( isset( $location['ip'] ) ) {
315
+            $key = 'community-events-' . md5( $location['ip'] );
316
+        } elseif ( isset( $location['latitude'], $location['longitude'] ) ) {
317
+            $key = 'community-events-' . md5( $location['latitude'] . $location['longitude'] );
318
+        }
319
+
320
+        return $key;
321
+    }
322
+
323
+    /**
324
+     * Caches an array of events data from the Events API.
325
+     *
326
+     * @since 4.8.0
327
+     *
328
+     * @param array     $events     Response body from the API request.
329
+     * @param int|false $expiration Optional. Amount of time to cache the events. Defaults to false.
330
+     * @return bool true if events were cached; false if not.
331
+     */
332
+    protected function cache_events( $events, $expiration = false ) {
333
+        $set              = false;
334
+        $transient_key    = $this->get_events_transient_key( $events['location'] );
335
+        $cache_expiration = $expiration ? absint( $expiration ) : HOUR_IN_SECONDS * 12;
336
+
337
+        if ( $transient_key ) {
338
+            $set = set_site_transient( $transient_key, $events, $cache_expiration );
339
+        }
340
+
341
+        return $set;
342
+    }
343
+
344
+    /**
345
+     * Gets cached events.
346
+     *
347
+     * @since 4.8.0
348
+     * @since 5.5.2 Response no longer contains formatted date field. They're added
349
+     *              in `wp.communityEvents.populateDynamicEventFields()` now.
350
+     *
351
+     * @return array|false An array containing `location` and `events` items
352
+     *                     on success, false on failure.
353
+     */
354
+    public function get_cached_events() {
355
+        $cached_response = get_site_transient( $this->get_events_transient_key( $this->user_location ) );
356
+
357
+        if ( isset( $cached_response['events'] ) ) {
358
+            $cached_response['events'] = $this->trim_events( $cached_response['events'] );
359
+        }
360
+
361
+        return $cached_response;
362
+    }
363
+
364
+    /**
365
+     * Adds formatted date and time items for each event in an API response.
366
+     *
367
+     * This has to be called after the data is pulled from the cache, because
368
+     * the cached events are shared by all users. If it was called before storing
369
+     * the cache, then all users would see the events in the localized data/time
370
+     * of the user who triggered the cache refresh, rather than their own.
371
+     *
372
+     * @since 4.8.0
373
+     * @deprecated 5.6.0 No longer used in core.
374
+     *
375
+     * @param array $response_body The response which contains the events.
376
+     * @return array The response with dates and times formatted.
377
+     */
378
+    protected function format_event_data_time( $response_body ) {
379
+        _deprecated_function(
380
+            __METHOD__,
381
+            '5.5.2',
382
+            'This is no longer used by core, and only kept for backward compatibility.'
383
+        );
384
+
385
+        if ( isset( $response_body['events'] ) ) {
386
+            foreach ( $response_body['events'] as $key => $event ) {
387
+                $timestamp = strtotime( $event['date'] );
388
+
389
+                /*
390 390
 				 * The `date_format` option is not used because it's important
391 391
 				 * in this context to keep the day of the week in the formatted date,
392 392
 				 * so that users can tell at a glance if the event is on a day they
393 393
 				 * are available, without having to open the link.
394 394
 				 */
395
-				/* translators: Date format for upcoming events on the dashboard. Include the day of the week. See https://www.php.net/manual/datetime.format.php */
396
-				$formatted_date = date_i18n( __( 'l, M j, Y' ), $timestamp );
397
-				$formatted_time = date_i18n( get_option( 'time_format' ), $timestamp );
398
-
399
-				if ( isset( $event['end_date'] ) ) {
400
-					$end_timestamp      = strtotime( $event['end_date'] );
401
-					$formatted_end_date = date_i18n( __( 'l, M j, Y' ), $end_timestamp );
402
-
403
-					if ( 'meetup' !== $event['type'] && $formatted_end_date !== $formatted_date ) {
404
-						/* translators: Upcoming events month format. See https://www.php.net/manual/datetime.format.php */
405
-						$start_month = date_i18n( _x( 'F', 'upcoming events month format' ), $timestamp );
406
-						$end_month   = date_i18n( _x( 'F', 'upcoming events month format' ), $end_timestamp );
407
-
408
-						if ( $start_month === $end_month ) {
409
-							$formatted_date = sprintf(
410
-								/* translators: Date string for upcoming events. 1: Month, 2: Starting day, 3: Ending day, 4: Year. */
411
-								__( '%1$s %2$d–%3$d, %4$d' ),
412
-								$start_month,
413
-								/* translators: Upcoming events day format. See https://www.php.net/manual/datetime.format.php */
414
-								date_i18n( _x( 'j', 'upcoming events day format' ), $timestamp ),
415
-								date_i18n( _x( 'j', 'upcoming events day format' ), $end_timestamp ),
416
-								/* translators: Upcoming events year format. See https://www.php.net/manual/datetime.format.php */
417
-								date_i18n( _x( 'Y', 'upcoming events year format' ), $timestamp )
418
-							);
419
-						} else {
420
-							$formatted_date = sprintf(
421
-								/* translators: Date string for upcoming events. 1: Starting month, 2: Starting day, 3: Ending month, 4: Ending day, 5: Year. */
422
-								__( '%1$s %2$d – %3$s %4$d, %5$d' ),
423
-								$start_month,
424
-								date_i18n( _x( 'j', 'upcoming events day format' ), $timestamp ),
425
-								$end_month,
426
-								date_i18n( _x( 'j', 'upcoming events day format' ), $end_timestamp ),
427
-								date_i18n( _x( 'Y', 'upcoming events year format' ), $timestamp )
428
-							);
429
-						}
430
-
431
-						$formatted_date = wp_maybe_decline_date( $formatted_date, 'F j, Y' );
432
-					}
433
-				}
434
-
435
-				$response_body['events'][ $key ]['formatted_date'] = $formatted_date;
436
-				$response_body['events'][ $key ]['formatted_time'] = $formatted_time;
437
-			}
438
-		}
439
-
440
-		return $response_body;
441
-	}
442
-
443
-	/**
444
-	 * Prepares the event list for presentation.
445
-	 *
446
-	 * Discards expired events, and makes WordCamps "sticky." Attendees need more
447
-	 * advanced notice about WordCamps than they do for meetups, so camps should
448
-	 * appear in the list sooner. If a WordCamp is coming up, the API will "stick"
449
-	 * it in the response, even if it wouldn't otherwise appear. When that happens,
450
-	 * the event will be at the end of the list, and will need to be moved into a
451
-	 * higher position, so that it doesn't get trimmed off.
452
-	 *
453
-	 * @since 4.8.0
454
-	 * @since 4.9.7 Stick a WordCamp to the final list.
455
-	 * @since 5.5.2 Accepts and returns only the events, rather than an entire HTTP response.
456
-	 * @since 6.0.0 Decode HTML entities from the event title.
457
-	 *
458
-	 * @param array $events The events that will be prepared.
459
-	 * @return array The response body with events trimmed.
460
-	 */
461
-	protected function trim_events( array $events ) {
462
-		$future_events = array();
463
-
464
-		foreach ( $events as $event ) {
465
-			/*
395
+                /* translators: Date format for upcoming events on the dashboard. Include the day of the week. See https://www.php.net/manual/datetime.format.php */
396
+                $formatted_date = date_i18n( __( 'l, M j, Y' ), $timestamp );
397
+                $formatted_time = date_i18n( get_option( 'time_format' ), $timestamp );
398
+
399
+                if ( isset( $event['end_date'] ) ) {
400
+                    $end_timestamp      = strtotime( $event['end_date'] );
401
+                    $formatted_end_date = date_i18n( __( 'l, M j, Y' ), $end_timestamp );
402
+
403
+                    if ( 'meetup' !== $event['type'] && $formatted_end_date !== $formatted_date ) {
404
+                        /* translators: Upcoming events month format. See https://www.php.net/manual/datetime.format.php */
405
+                        $start_month = date_i18n( _x( 'F', 'upcoming events month format' ), $timestamp );
406
+                        $end_month   = date_i18n( _x( 'F', 'upcoming events month format' ), $end_timestamp );
407
+
408
+                        if ( $start_month === $end_month ) {
409
+                            $formatted_date = sprintf(
410
+                                /* translators: Date string for upcoming events. 1: Month, 2: Starting day, 3: Ending day, 4: Year. */
411
+                                __( '%1$s %2$d–%3$d, %4$d' ),
412
+                                $start_month,
413
+                                /* translators: Upcoming events day format. See https://www.php.net/manual/datetime.format.php */
414
+                                date_i18n( _x( 'j', 'upcoming events day format' ), $timestamp ),
415
+                                date_i18n( _x( 'j', 'upcoming events day format' ), $end_timestamp ),
416
+                                /* translators: Upcoming events year format. See https://www.php.net/manual/datetime.format.php */
417
+                                date_i18n( _x( 'Y', 'upcoming events year format' ), $timestamp )
418
+                            );
419
+                        } else {
420
+                            $formatted_date = sprintf(
421
+                                /* translators: Date string for upcoming events. 1: Starting month, 2: Starting day, 3: Ending month, 4: Ending day, 5: Year. */
422
+                                __( '%1$s %2$d – %3$s %4$d, %5$d' ),
423
+                                $start_month,
424
+                                date_i18n( _x( 'j', 'upcoming events day format' ), $timestamp ),
425
+                                $end_month,
426
+                                date_i18n( _x( 'j', 'upcoming events day format' ), $end_timestamp ),
427
+                                date_i18n( _x( 'Y', 'upcoming events year format' ), $timestamp )
428
+                            );
429
+                        }
430
+
431
+                        $formatted_date = wp_maybe_decline_date( $formatted_date, 'F j, Y' );
432
+                    }
433
+                }
434
+
435
+                $response_body['events'][ $key ]['formatted_date'] = $formatted_date;
436
+                $response_body['events'][ $key ]['formatted_time'] = $formatted_time;
437
+            }
438
+        }
439
+
440
+        return $response_body;
441
+    }
442
+
443
+    /**
444
+     * Prepares the event list for presentation.
445
+     *
446
+     * Discards expired events, and makes WordCamps "sticky." Attendees need more
447
+     * advanced notice about WordCamps than they do for meetups, so camps should
448
+     * appear in the list sooner. If a WordCamp is coming up, the API will "stick"
449
+     * it in the response, even if it wouldn't otherwise appear. When that happens,
450
+     * the event will be at the end of the list, and will need to be moved into a
451
+     * higher position, so that it doesn't get trimmed off.
452
+     *
453
+     * @since 4.8.0
454
+     * @since 4.9.7 Stick a WordCamp to the final list.
455
+     * @since 5.5.2 Accepts and returns only the events, rather than an entire HTTP response.
456
+     * @since 6.0.0 Decode HTML entities from the event title.
457
+     *
458
+     * @param array $events The events that will be prepared.
459
+     * @return array The response body with events trimmed.
460
+     */
461
+    protected function trim_events( array $events ) {
462
+        $future_events = array();
463
+
464
+        foreach ( $events as $event ) {
465
+            /*
466 466
 			 * The API's `date` and `end_date` fields are in the _event's_ local timezone, but UTC is needed so
467 467
 			 * it can be converted to the _user's_ local time.
468 468
 			 */
469
-			$end_time = (int) $event['end_unix_timestamp'];
470
-
471
-			if ( time() < $end_time ) {
472
-				// Decode HTML entities from the event title.
473
-				$event['title'] = html_entity_decode( $event['title'], ENT_QUOTES, 'UTF-8' );
474
-
475
-				array_push( $future_events, $event );
476
-			}
477
-		}
478
-
479
-		$future_wordcamps = array_filter(
480
-			$future_events,
481
-			static function( $wordcamp ) {
482
-				return 'wordcamp' === $wordcamp['type'];
483
-			}
484
-		);
485
-
486
-		$future_wordcamps    = array_values( $future_wordcamps ); // Remove gaps in indices.
487
-		$trimmed_events      = array_slice( $future_events, 0, 3 );
488
-		$trimmed_event_types = wp_list_pluck( $trimmed_events, 'type' );
489
-
490
-		// Make sure the soonest upcoming WordCamp is pinned in the list.
491
-		if ( $future_wordcamps && ! in_array( 'wordcamp', $trimmed_event_types, true ) ) {
492
-			array_pop( $trimmed_events );
493
-			array_push( $trimmed_events, $future_wordcamps[0] );
494
-		}
495
-
496
-		return $trimmed_events;
497
-	}
498
-
499
-	/**
500
-	 * Logs responses to Events API requests.
501
-	 *
502
-	 * @since 4.8.0
503
-	 * @deprecated 4.9.0 Use a plugin instead. See #41217 for an example.
504
-	 *
505
-	 * @param string $message A description of what occurred.
506
-	 * @param array  $details Details that provide more context for the
507
-	 *                        log entry.
508
-	 */
509
-	protected function maybe_log_events_response( $message, $details ) {
510
-		_deprecated_function( __METHOD__, '4.9.0' );
511
-
512
-		if ( ! WP_DEBUG_LOG ) {
513
-			return;
514
-		}
515
-
516
-		error_log(
517
-			sprintf(
518
-				'%s: %s. Details: %s',
519
-				__METHOD__,
520
-				trim( $message, '.' ),
521
-				wp_json_encode( $details )
522
-			)
523
-		);
524
-	}
469
+            $end_time = (int) $event['end_unix_timestamp'];
470
+
471
+            if ( time() < $end_time ) {
472
+                // Decode HTML entities from the event title.
473
+                $event['title'] = html_entity_decode( $event['title'], ENT_QUOTES, 'UTF-8' );
474
+
475
+                array_push( $future_events, $event );
476
+            }
477
+        }
478
+
479
+        $future_wordcamps = array_filter(
480
+            $future_events,
481
+            static function( $wordcamp ) {
482
+                return 'wordcamp' === $wordcamp['type'];
483
+            }
484
+        );
485
+
486
+        $future_wordcamps    = array_values( $future_wordcamps ); // Remove gaps in indices.
487
+        $trimmed_events      = array_slice( $future_events, 0, 3 );
488
+        $trimmed_event_types = wp_list_pluck( $trimmed_events, 'type' );
489
+
490
+        // Make sure the soonest upcoming WordCamp is pinned in the list.
491
+        if ( $future_wordcamps && ! in_array( 'wordcamp', $trimmed_event_types, true ) ) {
492
+            array_pop( $trimmed_events );
493
+            array_push( $trimmed_events, $future_wordcamps[0] );
494
+        }
495
+
496
+        return $trimmed_events;
497
+    }
498
+
499
+    /**
500
+     * Logs responses to Events API requests.
501
+     *
502
+     * @since 4.8.0
503
+     * @deprecated 4.9.0 Use a plugin instead. See #41217 for an example.
504
+     *
505
+     * @param string $message A description of what occurred.
506
+     * @param array  $details Details that provide more context for the
507
+     *                        log entry.
508
+     */
509
+    protected function maybe_log_events_response( $message, $details ) {
510
+        _deprecated_function( __METHOD__, '4.9.0' );
511
+
512
+        if ( ! WP_DEBUG_LOG ) {
513
+            return;
514
+        }
515
+
516
+        error_log(
517
+            sprintf(
518
+                '%s: %s. Details: %s',
519
+                __METHOD__,
520
+                trim( $message, '.' ),
521
+                wp_json_encode( $details )
522
+            )
523
+        );
524
+    }
525 525
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/widgets.php 1 patch
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -15,50 +15,50 @@  discard block
 block discarded – undo
15 15
  * @global array $wp_registered_widget_controls
16 16
  */
17 17
 function wp_list_widgets() {
18
-	global $wp_registered_widgets, $wp_registered_widget_controls;
19
-
20
-	$sort = $wp_registered_widgets;
21
-	usort( $sort, '_sort_name_callback' );
22
-	$done = array();
23
-
24
-	foreach ( $sort as $widget ) {
25
-		if ( in_array( $widget['callback'], $done, true ) ) { // We already showed this multi-widget.
26
-			continue;
27
-		}
28
-
29
-		$sidebar = is_active_widget( $widget['callback'], $widget['id'], false, false );
30
-		$done[]  = $widget['callback'];
31
-
32
-		if ( ! isset( $widget['params'][0] ) ) {
33
-			$widget['params'][0] = array();
34
-		}
35
-
36
-		$args = array(
37
-			'widget_id'   => $widget['id'],
38
-			'widget_name' => $widget['name'],
39
-			'_display'    => 'template',
40
-		);
41
-
42
-		if ( isset( $wp_registered_widget_controls[ $widget['id'] ]['id_base'] ) && isset( $widget['params'][0]['number'] ) ) {
43
-			$id_base            = $wp_registered_widget_controls[ $widget['id'] ]['id_base'];
44
-			$args['_temp_id']   = "$id_base-__i__";
45
-			$args['_multi_num'] = next_widget_id_number( $id_base );
46
-			$args['_add']       = 'multi';
47
-		} else {
48
-			$args['_add'] = 'single';
49
-			if ( $sidebar ) {
50
-				$args['_hide'] = '1';
51
-			}
52
-		}
53
-
54
-		$control_args = array(
55
-			0 => $args,
56
-			1 => $widget['params'][0],
57
-		);
58
-		$sidebar_args = wp_list_widget_controls_dynamic_sidebar( $control_args );
59
-
60
-		wp_widget_control( ...$sidebar_args );
61
-	}
18
+    global $wp_registered_widgets, $wp_registered_widget_controls;
19
+
20
+    $sort = $wp_registered_widgets;
21
+    usort( $sort, '_sort_name_callback' );
22
+    $done = array();
23
+
24
+    foreach ( $sort as $widget ) {
25
+        if ( in_array( $widget['callback'], $done, true ) ) { // We already showed this multi-widget.
26
+            continue;
27
+        }
28
+
29
+        $sidebar = is_active_widget( $widget['callback'], $widget['id'], false, false );
30
+        $done[]  = $widget['callback'];
31
+
32
+        if ( ! isset( $widget['params'][0] ) ) {
33
+            $widget['params'][0] = array();
34
+        }
35
+
36
+        $args = array(
37
+            'widget_id'   => $widget['id'],
38
+            'widget_name' => $widget['name'],
39
+            '_display'    => 'template',
40
+        );
41
+
42
+        if ( isset( $wp_registered_widget_controls[ $widget['id'] ]['id_base'] ) && isset( $widget['params'][0]['number'] ) ) {
43
+            $id_base            = $wp_registered_widget_controls[ $widget['id'] ]['id_base'];
44
+            $args['_temp_id']   = "$id_base-__i__";
45
+            $args['_multi_num'] = next_widget_id_number( $id_base );
46
+            $args['_add']       = 'multi';
47
+        } else {
48
+            $args['_add'] = 'single';
49
+            if ( $sidebar ) {
50
+                $args['_hide'] = '1';
51
+            }
52
+        }
53
+
54
+        $control_args = array(
55
+            0 => $args,
56
+            1 => $widget['params'][0],
57
+        );
58
+        $sidebar_args = wp_list_widget_controls_dynamic_sidebar( $control_args );
59
+
60
+        wp_widget_control( ...$sidebar_args );
61
+    }
62 62
 }
63 63
 
64 64
 /**
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
  * @return int
71 71
  */
72 72
 function _sort_name_callback( $a, $b ) {
73
-	return strnatcasecmp( $a['name'], $b['name'] );
73
+    return strnatcasecmp( $a['name'], $b['name'] );
74 74
 }
75 75
 
76 76
 /**
@@ -83,19 +83,19 @@  discard block
 block discarded – undo
83 83
  * @param string $sidebar_name Optional. Sidebar name. Default empty.
84 84
  */
85 85
 function wp_list_widget_controls( $sidebar, $sidebar_name = '' ) {
86
-	add_filter( 'dynamic_sidebar_params', 'wp_list_widget_controls_dynamic_sidebar' );
86
+    add_filter( 'dynamic_sidebar_params', 'wp_list_widget_controls_dynamic_sidebar' );
87 87
 
88
-	$description = wp_sidebar_description( $sidebar );
88
+    $description = wp_sidebar_description( $sidebar );
89 89
 
90
-	echo '<div id="' . esc_attr( $sidebar ) . '" class="widgets-sortables">';
90
+    echo '<div id="' . esc_attr( $sidebar ) . '" class="widgets-sortables">';
91 91
 
92
-	if ( $sidebar_name ) {
93
-		$add_to = sprintf(
94
-			/* translators: %s: Widgets sidebar name. */
95
-			__( 'Add to: %s' ),
96
-			$sidebar_name
97
-		);
98
-		?>
92
+    if ( $sidebar_name ) {
93
+        $add_to = sprintf(
94
+            /* translators: %s: Widgets sidebar name. */
95
+            __( 'Add to: %s' ),
96
+            $sidebar_name
97
+        );
98
+        ?>
99 99
 		<div class="sidebar-name" data-add-to="<?php echo esc_attr( $add_to ); ?>">
100 100
 			<button type="button" class="handlediv hide-if-no-js" aria-expanded="true">
101 101
 				<span class="screen-reader-text"><?php echo esc_html( $sidebar_name ); ?></span>
@@ -104,19 +104,19 @@  discard block
 block discarded – undo
104 104
 			<h2><?php echo esc_html( $sidebar_name ); ?> <span class="spinner"></span></h2>
105 105
 		</div>
106 106
 		<?php
107
-	}
107
+    }
108 108
 
109
-	if ( ! empty( $description ) ) {
110
-		?>
109
+    if ( ! empty( $description ) ) {
110
+        ?>
111 111
 		<div class="sidebar-description">
112 112
 			<p class="description"><?php echo $description; ?></p>
113 113
 		</div>
114 114
 		<?php
115
-	}
115
+    }
116 116
 
117
-	dynamic_sidebar( $sidebar );
117
+    dynamic_sidebar( $sidebar );
118 118
 
119
-	echo '</div>';
119
+    echo '</div>';
120 120
 }
121 121
 
122 122
 /**
@@ -130,25 +130,25 @@  discard block
 block discarded – undo
130 130
  * @return array
131 131
  */
132 132
 function wp_list_widget_controls_dynamic_sidebar( $params ) {
133
-	global $wp_registered_widgets;
134
-	static $i = 0;
135
-	$i++;
133
+    global $wp_registered_widgets;
134
+    static $i = 0;
135
+    $i++;
136 136
 
137
-	$widget_id = $params[0]['widget_id'];
138
-	$id        = isset( $params[0]['_temp_id'] ) ? $params[0]['_temp_id'] : $widget_id;
139
-	$hidden    = isset( $params[0]['_hide'] ) ? ' style="display:none;"' : '';
137
+    $widget_id = $params[0]['widget_id'];
138
+    $id        = isset( $params[0]['_temp_id'] ) ? $params[0]['_temp_id'] : $widget_id;
139
+    $hidden    = isset( $params[0]['_hide'] ) ? ' style="display:none;"' : '';
140 140
 
141
-	$params[0]['before_widget'] = "<div id='widget-{$i}_{$id}' class='widget'$hidden>";
142
-	$params[0]['after_widget']  = '</div>';
143
-	$params[0]['before_title']  = '%BEG_OF_TITLE%'; // Deprecated.
144
-	$params[0]['after_title']   = '%END_OF_TITLE%'; // Deprecated.
141
+    $params[0]['before_widget'] = "<div id='widget-{$i}_{$id}' class='widget'$hidden>";
142
+    $params[0]['after_widget']  = '</div>';
143
+    $params[0]['before_title']  = '%BEG_OF_TITLE%'; // Deprecated.
144
+    $params[0]['after_title']   = '%END_OF_TITLE%'; // Deprecated.
145 145
 
146
-	if ( is_callable( $wp_registered_widgets[ $widget_id ]['callback'] ) ) {
147
-		$wp_registered_widgets[ $widget_id ]['_callback'] = $wp_registered_widgets[ $widget_id ]['callback'];
148
-		$wp_registered_widgets[ $widget_id ]['callback']  = 'wp_widget_control';
149
-	}
146
+    if ( is_callable( $wp_registered_widgets[ $widget_id ]['callback'] ) ) {
147
+        $wp_registered_widgets[ $widget_id ]['_callback'] = $wp_registered_widgets[ $widget_id ]['callback'];
148
+        $wp_registered_widgets[ $widget_id ]['callback']  = 'wp_widget_control';
149
+    }
150 150
 
151
-	return $params;
151
+    return $params;
152 152
 }
153 153
 
154 154
 /**
@@ -158,17 +158,17 @@  discard block
 block discarded – undo
158 158
  * @return int
159 159
  */
160 160
 function next_widget_id_number( $id_base ) {
161
-	global $wp_registered_widgets;
162
-	$number = 1;
161
+    global $wp_registered_widgets;
162
+    $number = 1;
163 163
 
164
-	foreach ( $wp_registered_widgets as $widget_id => $widget ) {
165
-		if ( preg_match( '/' . preg_quote( $id_base, '/' ) . '-([0-9]+)$/', $widget_id, $matches ) ) {
166
-			$number = max( $number, $matches[1] );
167
-		}
168
-	}
169
-	$number++;
164
+    foreach ( $wp_registered_widgets as $widget_id => $widget ) {
165
+        if ( preg_match( '/' . preg_quote( $id_base, '/' ) . '-([0-9]+)$/', $widget_id, $matches ) ) {
166
+            $number = max( $number, $matches[1] );
167
+        }
168
+    }
169
+    $number++;
170 170
 
171
-	return $number;
171
+    return $number;
172 172
 }
173 173
 
174 174
 /**
@@ -186,74 +186,74 @@  discard block
 block discarded – undo
186 186
  * @return array
187 187
  */
188 188
 function wp_widget_control( $sidebar_args ) {
189
-	global $wp_registered_widgets, $wp_registered_widget_controls, $sidebars_widgets;
190
-
191
-	$widget_id  = $sidebar_args['widget_id'];
192
-	$sidebar_id = isset( $sidebar_args['id'] ) ? $sidebar_args['id'] : false;
193
-	$key        = $sidebar_id ? array_search( $widget_id, $sidebars_widgets[ $sidebar_id ], true ) : '-1'; // Position of widget in sidebar.
194
-	$control    = isset( $wp_registered_widget_controls[ $widget_id ] ) ? $wp_registered_widget_controls[ $widget_id ] : array();
195
-	$widget     = $wp_registered_widgets[ $widget_id ];
196
-
197
-	$id_format     = $widget['id'];
198
-	$widget_number = isset( $control['params'][0]['number'] ) ? $control['params'][0]['number'] : '';
199
-	$id_base       = isset( $control['id_base'] ) ? $control['id_base'] : $widget_id;
200
-	$width         = isset( $control['width'] ) ? $control['width'] : '';
201
-	$height        = isset( $control['height'] ) ? $control['height'] : '';
202
-	$multi_number  = isset( $sidebar_args['_multi_num'] ) ? $sidebar_args['_multi_num'] : '';
203
-	$add_new       = isset( $sidebar_args['_add'] ) ? $sidebar_args['_add'] : '';
204
-
205
-	$before_form           = isset( $sidebar_args['before_form'] ) ? $sidebar_args['before_form'] : '<form method="post">';
206
-	$after_form            = isset( $sidebar_args['after_form'] ) ? $sidebar_args['after_form'] : '</form>';
207
-	$before_widget_content = isset( $sidebar_args['before_widget_content'] ) ? $sidebar_args['before_widget_content'] : '<div class="widget-content">';
208
-	$after_widget_content  = isset( $sidebar_args['after_widget_content'] ) ? $sidebar_args['after_widget_content'] : '</div>';
209
-
210
-	$query_arg = array( 'editwidget' => $widget['id'] );
211
-	if ( $add_new ) {
212
-		$query_arg['addnew'] = 1;
213
-		if ( $multi_number ) {
214
-			$query_arg['num']  = $multi_number;
215
-			$query_arg['base'] = $id_base;
216
-		}
217
-	} else {
218
-		$query_arg['sidebar'] = $sidebar_id;
219
-		$query_arg['key']     = $key;
220
-	}
221
-
222
-	/*
189
+    global $wp_registered_widgets, $wp_registered_widget_controls, $sidebars_widgets;
190
+
191
+    $widget_id  = $sidebar_args['widget_id'];
192
+    $sidebar_id = isset( $sidebar_args['id'] ) ? $sidebar_args['id'] : false;
193
+    $key        = $sidebar_id ? array_search( $widget_id, $sidebars_widgets[ $sidebar_id ], true ) : '-1'; // Position of widget in sidebar.
194
+    $control    = isset( $wp_registered_widget_controls[ $widget_id ] ) ? $wp_registered_widget_controls[ $widget_id ] : array();
195
+    $widget     = $wp_registered_widgets[ $widget_id ];
196
+
197
+    $id_format     = $widget['id'];
198
+    $widget_number = isset( $control['params'][0]['number'] ) ? $control['params'][0]['number'] : '';
199
+    $id_base       = isset( $control['id_base'] ) ? $control['id_base'] : $widget_id;
200
+    $width         = isset( $control['width'] ) ? $control['width'] : '';
201
+    $height        = isset( $control['height'] ) ? $control['height'] : '';
202
+    $multi_number  = isset( $sidebar_args['_multi_num'] ) ? $sidebar_args['_multi_num'] : '';
203
+    $add_new       = isset( $sidebar_args['_add'] ) ? $sidebar_args['_add'] : '';
204
+
205
+    $before_form           = isset( $sidebar_args['before_form'] ) ? $sidebar_args['before_form'] : '<form method="post">';
206
+    $after_form            = isset( $sidebar_args['after_form'] ) ? $sidebar_args['after_form'] : '</form>';
207
+    $before_widget_content = isset( $sidebar_args['before_widget_content'] ) ? $sidebar_args['before_widget_content'] : '<div class="widget-content">';
208
+    $after_widget_content  = isset( $sidebar_args['after_widget_content'] ) ? $sidebar_args['after_widget_content'] : '</div>';
209
+
210
+    $query_arg = array( 'editwidget' => $widget['id'] );
211
+    if ( $add_new ) {
212
+        $query_arg['addnew'] = 1;
213
+        if ( $multi_number ) {
214
+            $query_arg['num']  = $multi_number;
215
+            $query_arg['base'] = $id_base;
216
+        }
217
+    } else {
218
+        $query_arg['sidebar'] = $sidebar_id;
219
+        $query_arg['key']     = $key;
220
+    }
221
+
222
+    /*
223 223
 	 * We aren't showing a widget control, we're outputting a template
224 224
 	 * for a multi-widget control.
225 225
 	 */
226
-	if ( isset( $sidebar_args['_display'] ) && 'template' === $sidebar_args['_display'] && $widget_number ) {
227
-		// number == -1 implies a template where id numbers are replaced by a generic '__i__'.
228
-		$control['params'][0]['number'] = -1;
229
-		// With id_base widget ID's are constructed like {$id_base}-{$id_number}.
230
-		if ( isset( $control['id_base'] ) ) {
231
-			$id_format = $control['id_base'] . '-__i__';
232
-		}
233
-	}
234
-
235
-	$wp_registered_widgets[ $widget_id ]['callback'] = $wp_registered_widgets[ $widget_id ]['_callback'];
236
-	unset( $wp_registered_widgets[ $widget_id ]['_callback'] );
237
-
238
-	$widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );
239
-	$has_form     = 'noform';
240
-
241
-	echo $sidebar_args['before_widget'];
242
-	?>
226
+    if ( isset( $sidebar_args['_display'] ) && 'template' === $sidebar_args['_display'] && $widget_number ) {
227
+        // number == -1 implies a template where id numbers are replaced by a generic '__i__'.
228
+        $control['params'][0]['number'] = -1;
229
+        // With id_base widget ID's are constructed like {$id_base}-{$id_number}.
230
+        if ( isset( $control['id_base'] ) ) {
231
+            $id_format = $control['id_base'] . '-__i__';
232
+        }
233
+    }
234
+
235
+    $wp_registered_widgets[ $widget_id ]['callback'] = $wp_registered_widgets[ $widget_id ]['_callback'];
236
+    unset( $wp_registered_widgets[ $widget_id ]['_callback'] );
237
+
238
+    $widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );
239
+    $has_form     = 'noform';
240
+
241
+    echo $sidebar_args['before_widget'];
242
+    ?>
243 243
 	<div class="widget-top">
244 244
 	<div class="widget-title-action">
245 245
 		<button type="button" class="widget-action hide-if-no-js" aria-expanded="false">
246 246
 			<span class="screen-reader-text edit">
247 247
 				<?php
248
-				/* translators: %s: Widget title. */
249
-				printf( __( 'Edit widget: %s' ), $widget_title );
250
-				?>
248
+                /* translators: %s: Widget title. */
249
+                printf( __( 'Edit widget: %s' ), $widget_title );
250
+                ?>
251 251
 			</span>
252 252
 			<span class="screen-reader-text add">
253 253
 				<?php
254
-				/* translators: %s: Widget title. */
255
-				printf( __( 'Add widget: %s' ), $widget_title );
256
-				?>
254
+                /* translators: %s: Widget title. */
255
+                printf( __( 'Add widget: %s' ), $widget_title );
256
+                ?>
257 257
 			</span>
258 258
 			<span class="toggle-indicator" aria-hidden="true"></span>
259 259
 		</button>
@@ -270,17 +270,17 @@  discard block
 block discarded – undo
270 270
 	<?php echo $before_form; ?>
271 271
 	<?php echo $before_widget_content; ?>
272 272
 	<?php
273
-	if ( isset( $control['callback'] ) ) {
274
-		$has_form = call_user_func_array( $control['callback'], $control['params'] );
275
-	} else {
276
-		echo "\t\t<p>" . __( 'There are no options for this widget.' ) . "</p>\n";
277
-	}
278
-
279
-	$noform_class = '';
280
-	if ( 'noform' === $has_form ) {
281
-		$noform_class = ' widget-control-noform';
282
-	}
283
-	?>
273
+    if ( isset( $control['callback'] ) ) {
274
+        $has_form = call_user_func_array( $control['callback'], $control['params'] );
275
+    } else {
276
+        echo "\t\t<p>" . __( 'There are no options for this widget.' ) . "</p>\n";
277
+    }
278
+
279
+    $noform_class = '';
280
+    if ( 'noform' === $has_form ) {
281
+        $noform_class = ' widget-control-noform';
282
+    }
283
+    ?>
284 284
 	<?php echo $after_widget_content; ?>
285 285
 	<input type="hidden" name="widget-id" class="widget-id" value="<?php echo esc_attr( $id_format ); ?>" />
286 286
 	<input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr( $id_base ); ?>" />
@@ -308,14 +308,14 @@  discard block
 block discarded – undo
308 308
 
309 309
 	<div class="widget-description">
310 310
 	<?php
311
-	$widget_description = wp_widget_description( $widget_id );
312
-	echo ( $widget_description ) ? "$widget_description\n" : "$widget_title\n";
313
-	?>
311
+    $widget_description = wp_widget_description( $widget_id );
312
+    echo ( $widget_description ) ? "$widget_description\n" : "$widget_title\n";
313
+    ?>
314 314
 	</div>
315 315
 	<?php
316
-	echo $sidebar_args['after_widget'];
316
+    echo $sidebar_args['after_widget'];
317 317
 
318
-	return $sidebar_args;
318
+    return $sidebar_args;
319 319
 }
320 320
 
321 321
 /**
@@ -323,5 +323,5 @@  discard block
 block discarded – undo
323 323
  * @return string
324 324
  */
325 325
 function wp_widgets_access_body_class( $classes ) {
326
-	return "$classes widgets_access ";
326
+    return "$classes widgets_access ";
327 327
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/class-wp-upgrader-skin.php 1 patch
Indentation   +226 added lines, -226 removed lines patch added patch discarded remove patch
@@ -15,263 +15,263 @@
 block discarded – undo
15 15
  */
16 16
 class WP_Upgrader_Skin {
17 17
 
18
-	/**
19
-	 * Holds the upgrader data.
20
-	 *
21
-	 * @since 2.8.0
22
-	 *
23
-	 * @var WP_Upgrader
24
-	 */
25
-	public $upgrader;
18
+    /**
19
+     * Holds the upgrader data.
20
+     *
21
+     * @since 2.8.0
22
+     *
23
+     * @var WP_Upgrader
24
+     */
25
+    public $upgrader;
26 26
 
27
-	/**
28
-	 * Whether header is done.
29
-	 *
30
-	 * @since 2.8.0
31
-	 *
32
-	 * @var bool
33
-	 */
34
-	public $done_header = false;
27
+    /**
28
+     * Whether header is done.
29
+     *
30
+     * @since 2.8.0
31
+     *
32
+     * @var bool
33
+     */
34
+    public $done_header = false;
35 35
 
36
-	/**
37
-	 * Whether footer is done.
38
-	 *
39
-	 * @since 2.8.0
40
-	 *
41
-	 * @var bool
42
-	 */
43
-	public $done_footer = false;
36
+    /**
37
+     * Whether footer is done.
38
+     *
39
+     * @since 2.8.0
40
+     *
41
+     * @var bool
42
+     */
43
+    public $done_footer = false;
44 44
 
45
-	/**
46
-	 * Holds the result of an upgrade.
47
-	 *
48
-	 * @since 2.8.0
49
-	 *
50
-	 * @var string|bool|WP_Error
51
-	 */
52
-	public $result = false;
45
+    /**
46
+     * Holds the result of an upgrade.
47
+     *
48
+     * @since 2.8.0
49
+     *
50
+     * @var string|bool|WP_Error
51
+     */
52
+    public $result = false;
53 53
 
54
-	/**
55
-	 * Holds the options of an upgrade.
56
-	 *
57
-	 * @since 2.8.0
58
-	 *
59
-	 * @var array
60
-	 */
61
-	public $options = array();
54
+    /**
55
+     * Holds the options of an upgrade.
56
+     *
57
+     * @since 2.8.0
58
+     *
59
+     * @var array
60
+     */
61
+    public $options = array();
62 62
 
63
-	/**
64
-	 * Constructor.
65
-	 *
66
-	 * Sets up the generic skin for the WordPress Upgrader classes.
67
-	 *
68
-	 * @since 2.8.0
69
-	 *
70
-	 * @param array $args Optional. The WordPress upgrader skin arguments to
71
-	 *                    override default options. Default empty array.
72
-	 */
73
-	public function __construct( $args = array() ) {
74
-		$defaults      = array(
75
-			'url'     => '',
76
-			'nonce'   => '',
77
-			'title'   => '',
78
-			'context' => false,
79
-		);
80
-		$this->options = wp_parse_args( $args, $defaults );
81
-	}
63
+    /**
64
+     * Constructor.
65
+     *
66
+     * Sets up the generic skin for the WordPress Upgrader classes.
67
+     *
68
+     * @since 2.8.0
69
+     *
70
+     * @param array $args Optional. The WordPress upgrader skin arguments to
71
+     *                    override default options. Default empty array.
72
+     */
73
+    public function __construct( $args = array() ) {
74
+        $defaults      = array(
75
+            'url'     => '',
76
+            'nonce'   => '',
77
+            'title'   => '',
78
+            'context' => false,
79
+        );
80
+        $this->options = wp_parse_args( $args, $defaults );
81
+    }
82 82
 
83
-	/**
84
-	 * @since 2.8.0
85
-	 *
86
-	 * @param WP_Upgrader $upgrader
87
-	 */
88
-	public function set_upgrader( &$upgrader ) {
89
-		if ( is_object( $upgrader ) ) {
90
-			$this->upgrader =& $upgrader;
91
-		}
92
-		$this->add_strings();
93
-	}
83
+    /**
84
+     * @since 2.8.0
85
+     *
86
+     * @param WP_Upgrader $upgrader
87
+     */
88
+    public function set_upgrader( &$upgrader ) {
89
+        if ( is_object( $upgrader ) ) {
90
+            $this->upgrader =& $upgrader;
91
+        }
92
+        $this->add_strings();
93
+    }
94 94
 
95
-	/**
96
-	 * @since 3.0.0
97
-	 */
98
-	public function add_strings() {
99
-	}
95
+    /**
96
+     * @since 3.0.0
97
+     */
98
+    public function add_strings() {
99
+    }
100 100
 
101
-	/**
102
-	 * Sets the result of an upgrade.
103
-	 *
104
-	 * @since 2.8.0
105
-	 *
106
-	 * @param string|bool|WP_Error $result The result of an upgrade.
107
-	 */
108
-	public function set_result( $result ) {
109
-		$this->result = $result;
110
-	}
101
+    /**
102
+     * Sets the result of an upgrade.
103
+     *
104
+     * @since 2.8.0
105
+     *
106
+     * @param string|bool|WP_Error $result The result of an upgrade.
107
+     */
108
+    public function set_result( $result ) {
109
+        $this->result = $result;
110
+    }
111 111
 
112
-	/**
113
-	 * Displays a form to the user to request for their FTP/SSH details in order
114
-	 * to connect to the filesystem.
115
-	 *
116
-	 * @since 2.8.0
117
-	 * @since 4.6.0 The `$context` parameter default changed from `false` to an empty string.
118
-	 *
119
-	 * @see request_filesystem_credentials()
120
-	 *
121
-	 * @param bool|WP_Error $error                        Optional. Whether the current request has failed to connect,
122
-	 *                                                    or an error object. Default false.
123
-	 * @param string        $context                      Optional. Full path to the directory that is tested
124
-	 *                                                    for being writable. Default empty.
125
-	 * @param bool          $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
126
-	 * @return bool True on success, false on failure.
127
-	 */
128
-	public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
129
-		$url = $this->options['url'];
130
-		if ( ! $context ) {
131
-			$context = $this->options['context'];
132
-		}
133
-		if ( ! empty( $this->options['nonce'] ) ) {
134
-			$url = wp_nonce_url( $url, $this->options['nonce'] );
135
-		}
112
+    /**
113
+     * Displays a form to the user to request for their FTP/SSH details in order
114
+     * to connect to the filesystem.
115
+     *
116
+     * @since 2.8.0
117
+     * @since 4.6.0 The `$context` parameter default changed from `false` to an empty string.
118
+     *
119
+     * @see request_filesystem_credentials()
120
+     *
121
+     * @param bool|WP_Error $error                        Optional. Whether the current request has failed to connect,
122
+     *                                                    or an error object. Default false.
123
+     * @param string        $context                      Optional. Full path to the directory that is tested
124
+     *                                                    for being writable. Default empty.
125
+     * @param bool          $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
126
+     * @return bool True on success, false on failure.
127
+     */
128
+    public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
129
+        $url = $this->options['url'];
130
+        if ( ! $context ) {
131
+            $context = $this->options['context'];
132
+        }
133
+        if ( ! empty( $this->options['nonce'] ) ) {
134
+            $url = wp_nonce_url( $url, $this->options['nonce'] );
135
+        }
136 136
 
137
-		$extra_fields = array();
137
+        $extra_fields = array();
138 138
 
139
-		return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
140
-	}
139
+        return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
140
+    }
141 141
 
142
-	/**
143
-	 * @since 2.8.0
144
-	 */
145
-	public function header() {
146
-		if ( $this->done_header ) {
147
-			return;
148
-		}
149
-		$this->done_header = true;
150
-		echo '<div class="wrap">';
151
-		echo '<h1>' . $this->options['title'] . '</h1>';
152
-	}
142
+    /**
143
+     * @since 2.8.0
144
+     */
145
+    public function header() {
146
+        if ( $this->done_header ) {
147
+            return;
148
+        }
149
+        $this->done_header = true;
150
+        echo '<div class="wrap">';
151
+        echo '<h1>' . $this->options['title'] . '</h1>';
152
+    }
153 153
 
154
-	/**
155
-	 * @since 2.8.0
156
-	 */
157
-	public function footer() {
158
-		if ( $this->done_footer ) {
159
-			return;
160
-		}
161
-		$this->done_footer = true;
162
-		echo '</div>';
163
-	}
154
+    /**
155
+     * @since 2.8.0
156
+     */
157
+    public function footer() {
158
+        if ( $this->done_footer ) {
159
+            return;
160
+        }
161
+        $this->done_footer = true;
162
+        echo '</div>';
163
+    }
164 164
 
165
-	/**
166
-	 * @since 2.8.0
167
-	 *
168
-	 * @param string|WP_Error $errors Errors.
169
-	 */
170
-	public function error( $errors ) {
171
-		if ( ! $this->done_header ) {
172
-			$this->header();
173
-		}
174
-		if ( is_string( $errors ) ) {
175
-			$this->feedback( $errors );
176
-		} elseif ( is_wp_error( $errors ) && $errors->has_errors() ) {
177
-			foreach ( $errors->get_error_messages() as $message ) {
178
-				if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
179
-					$this->feedback( $message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
180
-				} else {
181
-					$this->feedback( $message );
182
-				}
183
-			}
184
-		}
185
-	}
165
+    /**
166
+     * @since 2.8.0
167
+     *
168
+     * @param string|WP_Error $errors Errors.
169
+     */
170
+    public function error( $errors ) {
171
+        if ( ! $this->done_header ) {
172
+            $this->header();
173
+        }
174
+        if ( is_string( $errors ) ) {
175
+            $this->feedback( $errors );
176
+        } elseif ( is_wp_error( $errors ) && $errors->has_errors() ) {
177
+            foreach ( $errors->get_error_messages() as $message ) {
178
+                if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
179
+                    $this->feedback( $message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
180
+                } else {
181
+                    $this->feedback( $message );
182
+                }
183
+            }
184
+        }
185
+    }
186 186
 
187
-	/**
188
-	 * @since 2.8.0
189
-	 * @since 5.9.0 Renamed `$string` (a PHP reserved keyword) to `$feedback` for PHP 8 named parameter support.
190
-	 *
191
-	 * @param string $feedback Message data.
192
-	 * @param mixed  ...$args  Optional text replacements.
193
-	 */
194
-	public function feedback( $feedback, ...$args ) {
195
-		if ( isset( $this->upgrader->strings[ $feedback ] ) ) {
196
-			$feedback = $this->upgrader->strings[ $feedback ];
197
-		}
187
+    /**
188
+     * @since 2.8.0
189
+     * @since 5.9.0 Renamed `$string` (a PHP reserved keyword) to `$feedback` for PHP 8 named parameter support.
190
+     *
191
+     * @param string $feedback Message data.
192
+     * @param mixed  ...$args  Optional text replacements.
193
+     */
194
+    public function feedback( $feedback, ...$args ) {
195
+        if ( isset( $this->upgrader->strings[ $feedback ] ) ) {
196
+            $feedback = $this->upgrader->strings[ $feedback ];
197
+        }
198 198
 
199
-		if ( strpos( $feedback, '%' ) !== false ) {
200
-			if ( $args ) {
201
-				$args     = array_map( 'strip_tags', $args );
202
-				$args     = array_map( 'esc_html', $args );
203
-				$feedback = vsprintf( $feedback, $args );
204
-			}
205
-		}
206
-		if ( empty( $feedback ) ) {
207
-			return;
208
-		}
209
-		show_message( $feedback );
210
-	}
199
+        if ( strpos( $feedback, '%' ) !== false ) {
200
+            if ( $args ) {
201
+                $args     = array_map( 'strip_tags', $args );
202
+                $args     = array_map( 'esc_html', $args );
203
+                $feedback = vsprintf( $feedback, $args );
204
+            }
205
+        }
206
+        if ( empty( $feedback ) ) {
207
+            return;
208
+        }
209
+        show_message( $feedback );
210
+    }
211 211
 
212
-	/**
213
-	 * Action to perform before an update.
214
-	 *
215
-	 * @since 2.8.0
216
-	 */
217
-	public function before() {}
212
+    /**
213
+     * Action to perform before an update.
214
+     *
215
+     * @since 2.8.0
216
+     */
217
+    public function before() {}
218 218
 
219
-	/**
220
-	 * Action to perform following an update.
221
-	 *
222
-	 * @since 2.8.0
223
-	 */
224
-	public function after() {}
219
+    /**
220
+     * Action to perform following an update.
221
+     *
222
+     * @since 2.8.0
223
+     */
224
+    public function after() {}
225 225
 
226
-	/**
227
-	 * Output JavaScript that calls function to decrement the update counts.
228
-	 *
229
-	 * @since 3.9.0
230
-	 *
231
-	 * @param string $type Type of update count to decrement. Likely values include 'plugin',
232
-	 *                     'theme', 'translation', etc.
233
-	 */
234
-	protected function decrement_update_count( $type ) {
235
-		if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
236
-			return;
237
-		}
226
+    /**
227
+     * Output JavaScript that calls function to decrement the update counts.
228
+     *
229
+     * @since 3.9.0
230
+     *
231
+     * @param string $type Type of update count to decrement. Likely values include 'plugin',
232
+     *                     'theme', 'translation', etc.
233
+     */
234
+    protected function decrement_update_count( $type ) {
235
+        if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
236
+            return;
237
+        }
238 238
 
239
-		if ( defined( 'IFRAME_REQUEST' ) ) {
240
-			echo '<script type="text/javascript">
239
+        if ( defined( 'IFRAME_REQUEST' ) ) {
240
+            echo '<script type="text/javascript">
241 241
 					if ( window.postMessage && JSON ) {
242 242
 						window.parent.postMessage( JSON.stringify( { action: "decrementUpdateCount", upgradeType: "' . $type . '" } ), window.location.protocol + "//" + window.location.hostname );
243 243
 					}
244 244
 				</script>';
245
-		} else {
246
-			echo '<script type="text/javascript">
245
+        } else {
246
+            echo '<script type="text/javascript">
247 247
 					(function( wp ) {
248 248
 						if ( wp && wp.updates && wp.updates.decrementCount ) {
249 249
 							wp.updates.decrementCount( "' . $type . '" );
250 250
 						}
251 251
 					})( window.wp );
252 252
 				</script>';
253
-		}
254
-	}
253
+        }
254
+    }
255 255
 
256
-	/**
257
-	 * @since 3.0.0
258
-	 */
259
-	public function bulk_header() {}
256
+    /**
257
+     * @since 3.0.0
258
+     */
259
+    public function bulk_header() {}
260 260
 
261
-	/**
262
-	 * @since 3.0.0
263
-	 */
264
-	public function bulk_footer() {}
261
+    /**
262
+     * @since 3.0.0
263
+     */
264
+    public function bulk_footer() {}
265 265
 
266
-	/**
267
-	 * Hides the `process_failed` error message when updating by uploading a zip file.
268
-	 *
269
-	 * @since 5.5.0
270
-	 *
271
-	 * @param WP_Error $wp_error WP_Error object.
272
-	 * @return bool
273
-	 */
274
-	public function hide_process_failed( $wp_error ) {
275
-		return false;
276
-	}
266
+    /**
267
+     * Hides the `process_failed` error message when updating by uploading a zip file.
268
+     *
269
+     * @since 5.5.0
270
+     *
271
+     * @param WP_Error $wp_error WP_Error object.
272
+     * @return bool
273
+     */
274
+    public function hide_process_failed( $wp_error ) {
275
+        return false;
276
+    }
277 277
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/class-wp-ajax-upgrader-skin.php 1 patch
Indentation   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -18,121 +18,121 @@
 block discarded – undo
18 18
  */
19 19
 class WP_Ajax_Upgrader_Skin extends Automatic_Upgrader_Skin {
20 20
 
21
-	/**
22
-	 * Holds the WP_Error object.
23
-	 *
24
-	 * @since 4.6.0
25
-	 *
26
-	 * @var null|WP_Error
27
-	 */
28
-	protected $errors = null;
21
+    /**
22
+     * Holds the WP_Error object.
23
+     *
24
+     * @since 4.6.0
25
+     *
26
+     * @var null|WP_Error
27
+     */
28
+    protected $errors = null;
29 29
 
30
-	/**
31
-	 * Constructor.
32
-	 *
33
-	 * Sets up the WordPress Ajax upgrader skin.
34
-	 *
35
-	 * @since 4.6.0
36
-	 *
37
-	 * @see WP_Upgrader_Skin::__construct()
38
-	 *
39
-	 * @param array $args Optional. The WordPress Ajax upgrader skin arguments to
40
-	 *                    override default options. See WP_Upgrader_Skin::__construct().
41
-	 *                    Default empty array.
42
-	 */
43
-	public function __construct( $args = array() ) {
44
-		parent::__construct( $args );
30
+    /**
31
+     * Constructor.
32
+     *
33
+     * Sets up the WordPress Ajax upgrader skin.
34
+     *
35
+     * @since 4.6.0
36
+     *
37
+     * @see WP_Upgrader_Skin::__construct()
38
+     *
39
+     * @param array $args Optional. The WordPress Ajax upgrader skin arguments to
40
+     *                    override default options. See WP_Upgrader_Skin::__construct().
41
+     *                    Default empty array.
42
+     */
43
+    public function __construct( $args = array() ) {
44
+        parent::__construct( $args );
45 45
 
46
-		$this->errors = new WP_Error();
47
-	}
46
+        $this->errors = new WP_Error();
47
+    }
48 48
 
49
-	/**
50
-	 * Retrieves the list of errors.
51
-	 *
52
-	 * @since 4.6.0
53
-	 *
54
-	 * @return WP_Error Errors during an upgrade.
55
-	 */
56
-	public function get_errors() {
57
-		return $this->errors;
58
-	}
49
+    /**
50
+     * Retrieves the list of errors.
51
+     *
52
+     * @since 4.6.0
53
+     *
54
+     * @return WP_Error Errors during an upgrade.
55
+     */
56
+    public function get_errors() {
57
+        return $this->errors;
58
+    }
59 59
 
60
-	/**
61
-	 * Retrieves a string for error messages.
62
-	 *
63
-	 * @since 4.6.0
64
-	 *
65
-	 * @return string Error messages during an upgrade.
66
-	 */
67
-	public function get_error_messages() {
68
-		$messages = array();
60
+    /**
61
+     * Retrieves a string for error messages.
62
+     *
63
+     * @since 4.6.0
64
+     *
65
+     * @return string Error messages during an upgrade.
66
+     */
67
+    public function get_error_messages() {
68
+        $messages = array();
69 69
 
70
-		foreach ( $this->errors->get_error_codes() as $error_code ) {
71
-			$error_data = $this->errors->get_error_data( $error_code );
70
+        foreach ( $this->errors->get_error_codes() as $error_code ) {
71
+            $error_data = $this->errors->get_error_data( $error_code );
72 72
 
73
-			if ( $error_data && is_string( $error_data ) ) {
74
-				$messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( strip_tags( $error_data ) );
75
-			} else {
76
-				$messages[] = $this->errors->get_error_message( $error_code );
77
-			}
78
-		}
73
+            if ( $error_data && is_string( $error_data ) ) {
74
+                $messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( strip_tags( $error_data ) );
75
+            } else {
76
+                $messages[] = $this->errors->get_error_message( $error_code );
77
+            }
78
+        }
79 79
 
80
-		return implode( ', ', $messages );
81
-	}
80
+        return implode( ', ', $messages );
81
+    }
82 82
 
83
-	/**
84
-	 * Stores an error message about the upgrade.
85
-	 *
86
-	 * @since 4.6.0
87
-	 * @since 5.3.0 Formalized the existing `...$args` parameter by adding it
88
-	 *              to the function signature.
89
-	 *
90
-	 * @param string|WP_Error $errors  Errors.
91
-	 * @param mixed           ...$args Optional text replacements.
92
-	 */
93
-	public function error( $errors, ...$args ) {
94
-		if ( is_string( $errors ) ) {
95
-			$string = $errors;
96
-			if ( ! empty( $this->upgrader->strings[ $string ] ) ) {
97
-				$string = $this->upgrader->strings[ $string ];
98
-			}
83
+    /**
84
+     * Stores an error message about the upgrade.
85
+     *
86
+     * @since 4.6.0
87
+     * @since 5.3.0 Formalized the existing `...$args` parameter by adding it
88
+     *              to the function signature.
89
+     *
90
+     * @param string|WP_Error $errors  Errors.
91
+     * @param mixed           ...$args Optional text replacements.
92
+     */
93
+    public function error( $errors, ...$args ) {
94
+        if ( is_string( $errors ) ) {
95
+            $string = $errors;
96
+            if ( ! empty( $this->upgrader->strings[ $string ] ) ) {
97
+                $string = $this->upgrader->strings[ $string ];
98
+            }
99 99
 
100
-			if ( false !== strpos( $string, '%' ) ) {
101
-				if ( ! empty( $args ) ) {
102
-					$string = vsprintf( $string, $args );
103
-				}
104
-			}
100
+            if ( false !== strpos( $string, '%' ) ) {
101
+                if ( ! empty( $args ) ) {
102
+                    $string = vsprintf( $string, $args );
103
+                }
104
+            }
105 105
 
106
-			// Count existing errors to generate a unique error code.
107
-			$errors_count = count( $this->errors->get_error_codes() );
108
-			$this->errors->add( 'unknown_upgrade_error_' . ( $errors_count + 1 ), $string );
109
-		} elseif ( is_wp_error( $errors ) ) {
110
-			foreach ( $errors->get_error_codes() as $error_code ) {
111
-				$this->errors->add( $error_code, $errors->get_error_message( $error_code ), $errors->get_error_data( $error_code ) );
112
-			}
113
-		}
106
+            // Count existing errors to generate a unique error code.
107
+            $errors_count = count( $this->errors->get_error_codes() );
108
+            $this->errors->add( 'unknown_upgrade_error_' . ( $errors_count + 1 ), $string );
109
+        } elseif ( is_wp_error( $errors ) ) {
110
+            foreach ( $errors->get_error_codes() as $error_code ) {
111
+                $this->errors->add( $error_code, $errors->get_error_message( $error_code ), $errors->get_error_data( $error_code ) );
112
+            }
113
+        }
114 114
 
115
-		parent::error( $errors, ...$args );
116
-	}
115
+        parent::error( $errors, ...$args );
116
+    }
117 117
 
118
-	/**
119
-	 * Stores a message about the upgrade.
120
-	 *
121
-	 * @since 4.6.0
122
-	 * @since 5.3.0 Formalized the existing `...$args` parameter by adding it
123
-	 *              to the function signature.
124
-	 * @since 5.9.0 Renamed `$data` to `$feedback` for PHP 8 named parameter support.
125
-	 *
126
-	 * @param string|array|WP_Error $feedback Message data.
127
-	 * @param mixed                 ...$args  Optional text replacements.
128
-	 */
129
-	public function feedback( $feedback, ...$args ) {
130
-		if ( is_wp_error( $feedback ) ) {
131
-			foreach ( $feedback->get_error_codes() as $error_code ) {
132
-				$this->errors->add( $error_code, $feedback->get_error_message( $error_code ), $feedback->get_error_data( $error_code ) );
133
-			}
134
-		}
118
+    /**
119
+     * Stores a message about the upgrade.
120
+     *
121
+     * @since 4.6.0
122
+     * @since 5.3.0 Formalized the existing `...$args` parameter by adding it
123
+     *              to the function signature.
124
+     * @since 5.9.0 Renamed `$data` to `$feedback` for PHP 8 named parameter support.
125
+     *
126
+     * @param string|array|WP_Error $feedback Message data.
127
+     * @param mixed                 ...$args  Optional text replacements.
128
+     */
129
+    public function feedback( $feedback, ...$args ) {
130
+        if ( is_wp_error( $feedback ) ) {
131
+            foreach ( $feedback->get_error_codes() as $error_code ) {
132
+                $this->errors->add( $error_code, $feedback->get_error_message( $error_code ), $feedback->get_error_data( $error_code ) );
133
+            }
134
+        }
135 135
 
136
-		parent::feedback( $feedback, ...$args );
137
-	}
136
+        parent::feedback( $feedback, ...$args );
137
+    }
138 138
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/ms.php 1 patch
Indentation   +788 added lines, -788 removed lines patch added patch discarded remove patch
@@ -16,40 +16,40 @@  discard block
 block discarded – undo
16 16
  * @return array The `$_FILES` array element with 'error' key set if file exceeds quota. 'error' is empty otherwise.
17 17
  */
18 18
 function check_upload_size( $file ) {
19
-	if ( get_site_option( 'upload_space_check_disabled' ) ) {
20
-		return $file;
21
-	}
19
+    if ( get_site_option( 'upload_space_check_disabled' ) ) {
20
+        return $file;
21
+    }
22 22
 
23
-	if ( $file['error'] > 0 ) { // There's already an error.
24
-		return $file;
25
-	}
23
+    if ( $file['error'] > 0 ) { // There's already an error.
24
+        return $file;
25
+    }
26 26
 
27
-	if ( defined( 'WP_IMPORTING' ) ) {
28
-		return $file;
29
-	}
27
+    if ( defined( 'WP_IMPORTING' ) ) {
28
+        return $file;
29
+    }
30 30
 
31
-	$space_left = get_upload_space_available();
31
+    $space_left = get_upload_space_available();
32 32
 
33
-	$file_size = filesize( $file['tmp_name'] );
34
-	if ( $space_left < $file_size ) {
35
-		/* translators: %s: Required disk space in kilobytes. */
36
-		$file['error'] = sprintf( __( 'Not enough space to upload. %s KB needed.' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) );
37
-	}
33
+    $file_size = filesize( $file['tmp_name'] );
34
+    if ( $space_left < $file_size ) {
35
+        /* translators: %s: Required disk space in kilobytes. */
36
+        $file['error'] = sprintf( __( 'Not enough space to upload. %s KB needed.' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) );
37
+    }
38 38
 
39
-	if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
40
-		/* translators: %s: Maximum allowed file size in kilobytes. */
41
-		$file['error'] = sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) );
42
-	}
39
+    if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) {
40
+        /* translators: %s: Maximum allowed file size in kilobytes. */
41
+        $file['error'] = sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) );
42
+    }
43 43
 
44
-	if ( upload_is_user_over_quota( false ) ) {
45
-		$file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
46
-	}
44
+    if ( upload_is_user_over_quota( false ) ) {
45
+        $file['error'] = __( 'You have used your space quota. Please delete files before uploading.' );
46
+    }
47 47
 
48
-	if ( $file['error'] > 0 && ! isset( $_POST['html-upload'] ) && ! wp_doing_ajax() ) {
49
-		wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
50
-	}
48
+    if ( $file['error'] > 0 && ! isset( $_POST['html-upload'] ) && ! wp_doing_ajax() ) {
49
+        wp_die( $file['error'] . ' <a href="javascript:history.go(-1)">' . __( 'Back' ) . '</a>' );
50
+    }
51 51
 
52
-	return $file;
52
+    return $file;
53 53
 }
54 54
 
55 55
 /**
@@ -64,69 +64,69 @@  discard block
 block discarded – undo
64 64
  * @param bool $drop    True if site's database tables should be dropped. Default false.
65 65
  */
66 66
 function wpmu_delete_blog( $blog_id, $drop = false ) {
67
-	global $wpdb;
68
-
69
-	$blog_id = (int) $blog_id;
70
-
71
-	$switch = false;
72
-	if ( get_current_blog_id() !== $blog_id ) {
73
-		$switch = true;
74
-		switch_to_blog( $blog_id );
75
-	}
76
-
77
-	$blog = get_site( $blog_id );
78
-
79
-	$current_network = get_network();
80
-
81
-	// If a full blog object is not available, do not destroy anything.
82
-	if ( $drop && ! $blog ) {
83
-		$drop = false;
84
-	}
85
-
86
-	// Don't destroy the initial, main, or root blog.
87
-	if ( $drop
88
-		&& ( 1 === $blog_id || is_main_site( $blog_id )
89
-			|| ( $blog->path === $current_network->path && $blog->domain === $current_network->domain ) )
90
-	) {
91
-		$drop = false;
92
-	}
93
-
94
-	$upload_path = trim( get_option( 'upload_path' ) );
95
-
96
-	// If ms_files_rewriting is enabled and upload_path is empty, wp_upload_dir is not reliable.
97
-	if ( $drop && get_site_option( 'ms_files_rewriting' ) && empty( $upload_path ) ) {
98
-		$drop = false;
99
-	}
100
-
101
-	if ( $drop ) {
102
-		wp_delete_site( $blog_id );
103
-	} else {
104
-		/** This action is documented in wp-includes/ms-blogs.php */
105
-		do_action_deprecated( 'delete_blog', array( $blog_id, false ), '5.1.0' );
106
-
107
-		$users = get_users(
108
-			array(
109
-				'blog_id' => $blog_id,
110
-				'fields'  => 'ids',
111
-			)
112
-		);
113
-
114
-		// Remove users from this blog.
115
-		if ( ! empty( $users ) ) {
116
-			foreach ( $users as $user_id ) {
117
-				remove_user_from_blog( $user_id, $blog_id );
118
-			}
119
-		}
120
-
121
-		update_blog_status( $blog_id, 'deleted', 1 );
122
-
123
-		/** This action is documented in wp-includes/ms-blogs.php */
124
-		do_action_deprecated( 'deleted_blog', array( $blog_id, false ), '5.1.0' );
125
-	}
126
-
127
-	if ( $switch ) {
128
-		restore_current_blog();
129
-	}
67
+    global $wpdb;
68
+
69
+    $blog_id = (int) $blog_id;
70
+
71
+    $switch = false;
72
+    if ( get_current_blog_id() !== $blog_id ) {
73
+        $switch = true;
74
+        switch_to_blog( $blog_id );
75
+    }
76
+
77
+    $blog = get_site( $blog_id );
78
+
79
+    $current_network = get_network();
80
+
81
+    // If a full blog object is not available, do not destroy anything.
82
+    if ( $drop && ! $blog ) {
83
+        $drop = false;
84
+    }
85
+
86
+    // Don't destroy the initial, main, or root blog.
87
+    if ( $drop
88
+        && ( 1 === $blog_id || is_main_site( $blog_id )
89
+            || ( $blog->path === $current_network->path && $blog->domain === $current_network->domain ) )
90
+    ) {
91
+        $drop = false;
92
+    }
93
+
94
+    $upload_path = trim( get_option( 'upload_path' ) );
95
+
96
+    // If ms_files_rewriting is enabled and upload_path is empty, wp_upload_dir is not reliable.
97
+    if ( $drop && get_site_option( 'ms_files_rewriting' ) && empty( $upload_path ) ) {
98
+        $drop = false;
99
+    }
100
+
101
+    if ( $drop ) {
102
+        wp_delete_site( $blog_id );
103
+    } else {
104
+        /** This action is documented in wp-includes/ms-blogs.php */
105
+        do_action_deprecated( 'delete_blog', array( $blog_id, false ), '5.1.0' );
106
+
107
+        $users = get_users(
108
+            array(
109
+                'blog_id' => $blog_id,
110
+                'fields'  => 'ids',
111
+            )
112
+        );
113
+
114
+        // Remove users from this blog.
115
+        if ( ! empty( $users ) ) {
116
+            foreach ( $users as $user_id ) {
117
+                remove_user_from_blog( $user_id, $blog_id );
118
+            }
119
+        }
120
+
121
+        update_blog_status( $blog_id, 'deleted', 1 );
122
+
123
+        /** This action is documented in wp-includes/ms-blogs.php */
124
+        do_action_deprecated( 'deleted_blog', array( $blog_id, false ), '5.1.0' );
125
+    }
126
+
127
+    if ( $switch ) {
128
+        restore_current_blog();
129
+    }
130 130
 }
131 131
 
132 132
 /**
@@ -142,74 +142,74 @@  discard block
 block discarded – undo
142 142
  * @return bool True if the user was deleted, otherwise false.
143 143
  */
144 144
 function wpmu_delete_user( $id ) {
145
-	global $wpdb;
146
-
147
-	if ( ! is_numeric( $id ) ) {
148
-		return false;
149
-	}
150
-
151
-	$id   = (int) $id;
152
-	$user = new WP_User( $id );
153
-
154
-	if ( ! $user->exists() ) {
155
-		return false;
156
-	}
157
-
158
-	// Global super-administrators are protected, and cannot be deleted.
159
-	$_super_admins = get_super_admins();
160
-	if ( in_array( $user->user_login, $_super_admins, true ) ) {
161
-		return false;
162
-	}
163
-
164
-	/**
165
-	 * Fires before a user is deleted from the network.
166
-	 *
167
-	 * @since MU (3.0.0)
168
-	 * @since 5.5.0 Added the `$user` parameter.
169
-	 *
170
-	 * @param int     $id   ID of the user about to be deleted from the network.
171
-	 * @param WP_User $user WP_User object of the user about to be deleted from the network.
172
-	 */
173
-	do_action( 'wpmu_delete_user', $id, $user );
174
-
175
-	$blogs = get_blogs_of_user( $id );
176
-
177
-	if ( ! empty( $blogs ) ) {
178
-		foreach ( $blogs as $blog ) {
179
-			switch_to_blog( $blog->userblog_id );
180
-			remove_user_from_blog( $id, $blog->userblog_id );
181
-
182
-			$post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) );
183
-			foreach ( (array) $post_ids as $post_id ) {
184
-				wp_delete_post( $post_id );
185
-			}
186
-
187
-			// Clean links.
188
-			$link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) );
189
-
190
-			if ( $link_ids ) {
191
-				foreach ( $link_ids as $link_id ) {
192
-					wp_delete_link( $link_id );
193
-				}
194
-			}
195
-
196
-			restore_current_blog();
197
-		}
198
-	}
199
-
200
-	$meta = $wpdb->get_col( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d", $id ) );
201
-	foreach ( $meta as $mid ) {
202
-		delete_metadata_by_mid( 'user', $mid );
203
-	}
204
-
205
-	$wpdb->delete( $wpdb->users, array( 'ID' => $id ) );
206
-
207
-	clean_user_cache( $user );
208
-
209
-	/** This action is documented in wp-admin/includes/user.php */
210
-	do_action( 'deleted_user', $id, null, $user );
211
-
212
-	return true;
145
+    global $wpdb;
146
+
147
+    if ( ! is_numeric( $id ) ) {
148
+        return false;
149
+    }
150
+
151
+    $id   = (int) $id;
152
+    $user = new WP_User( $id );
153
+
154
+    if ( ! $user->exists() ) {
155
+        return false;
156
+    }
157
+
158
+    // Global super-administrators are protected, and cannot be deleted.
159
+    $_super_admins = get_super_admins();
160
+    if ( in_array( $user->user_login, $_super_admins, true ) ) {
161
+        return false;
162
+    }
163
+
164
+    /**
165
+     * Fires before a user is deleted from the network.
166
+     *
167
+     * @since MU (3.0.0)
168
+     * @since 5.5.0 Added the `$user` parameter.
169
+     *
170
+     * @param int     $id   ID of the user about to be deleted from the network.
171
+     * @param WP_User $user WP_User object of the user about to be deleted from the network.
172
+     */
173
+    do_action( 'wpmu_delete_user', $id, $user );
174
+
175
+    $blogs = get_blogs_of_user( $id );
176
+
177
+    if ( ! empty( $blogs ) ) {
178
+        foreach ( $blogs as $blog ) {
179
+            switch_to_blog( $blog->userblog_id );
180
+            remove_user_from_blog( $id, $blog->userblog_id );
181
+
182
+            $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) );
183
+            foreach ( (array) $post_ids as $post_id ) {
184
+                wp_delete_post( $post_id );
185
+            }
186
+
187
+            // Clean links.
188
+            $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) );
189
+
190
+            if ( $link_ids ) {
191
+                foreach ( $link_ids as $link_id ) {
192
+                    wp_delete_link( $link_id );
193
+                }
194
+            }
195
+
196
+            restore_current_blog();
197
+        }
198
+    }
199
+
200
+    $meta = $wpdb->get_col( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d", $id ) );
201
+    foreach ( $meta as $mid ) {
202
+        delete_metadata_by_mid( 'user', $mid );
203
+    }
204
+
205
+    $wpdb->delete( $wpdb->users, array( 'ID' => $id ) );
206
+
207
+    clean_user_cache( $user );
208
+
209
+    /** This action is documented in wp-admin/includes/user.php */
210
+    do_action( 'deleted_user', $id, null, $user );
211
+
212
+    return true;
213 213
 }
214 214
 
215 215
 /**
@@ -222,28 +222,28 @@  discard block
 block discarded – undo
222 222
  * @return bool True if user is over upload space quota, otherwise false.
223 223
  */
224 224
 function upload_is_user_over_quota( $display_message = true ) {
225
-	if ( get_site_option( 'upload_space_check_disabled' ) ) {
226
-		return false;
227
-	}
228
-
229
-	$space_allowed = get_space_allowed();
230
-	if ( ! is_numeric( $space_allowed ) ) {
231
-		$space_allowed = 10; // Default space allowed is 10 MB.
232
-	}
233
-	$space_used = get_space_used();
234
-
235
-	if ( ( $space_allowed - $space_used ) < 0 ) {
236
-		if ( $display_message ) {
237
-			printf(
238
-				/* translators: %s: Allowed space allocation. */
239
-				__( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
240
-				size_format( $space_allowed * MB_IN_BYTES )
241
-			);
242
-		}
243
-		return true;
244
-	} else {
245
-		return false;
246
-	}
225
+    if ( get_site_option( 'upload_space_check_disabled' ) ) {
226
+        return false;
227
+    }
228
+
229
+    $space_allowed = get_space_allowed();
230
+    if ( ! is_numeric( $space_allowed ) ) {
231
+        $space_allowed = 10; // Default space allowed is 10 MB.
232
+    }
233
+    $space_used = get_space_used();
234
+
235
+    if ( ( $space_allowed - $space_used ) < 0 ) {
236
+        if ( $display_message ) {
237
+            printf(
238
+                /* translators: %s: Allowed space allocation. */
239
+                __( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
240
+                size_format( $space_allowed * MB_IN_BYTES )
241
+            );
242
+        }
243
+        return true;
244
+    } else {
245
+        return false;
246
+    }
247 247
 }
248 248
 
249 249
 /**
@@ -252,18 +252,18 @@  discard block
 block discarded – undo
252 252
  * @since MU (3.0.0)
253 253
  */
254 254
 function display_space_usage() {
255
-	$space_allowed = get_space_allowed();
256
-	$space_used    = get_space_used();
255
+    $space_allowed = get_space_allowed();
256
+    $space_used    = get_space_used();
257 257
 
258
-	$percent_used = ( $space_used / $space_allowed ) * 100;
258
+    $percent_used = ( $space_used / $space_allowed ) * 100;
259 259
 
260
-	$space = size_format( $space_allowed * MB_IN_BYTES );
261
-	?>
260
+    $space = size_format( $space_allowed * MB_IN_BYTES );
261
+    ?>
262 262
 	<strong>
263 263
 	<?php
264
-		/* translators: Storage space that's been used. 1: Percentage of used space, 2: Total space allowed in megabytes or gigabytes. */
265
-		printf( __( 'Used: %1$s%% of %2$s' ), number_format( $percent_used ), $space );
266
-	?>
264
+        /* translators: Storage space that's been used. 1: Percentage of used space, 2: Total space allowed in megabytes or gigabytes. */
265
+        printf( __( 'Used: %1$s%% of %2$s' ), number_format( $percent_used ), $space );
266
+    ?>
267 267
 	</strong>
268 268
 	<?php
269 269
 }
@@ -277,11 +277,11 @@  discard block
 block discarded – undo
277 277
  * @return int Max size in bytes
278 278
  */
279 279
 function fix_import_form_size( $size ) {
280
-	if ( upload_is_user_over_quota( false ) ) {
281
-		return 0;
282
-	}
283
-	$available = get_upload_space_available();
284
-	return min( $size, $available );
280
+    if ( upload_is_user_over_quota( false ) ) {
281
+        return 0;
282
+    }
283
+    $available = get_upload_space_available();
284
+    return min( $size, $available );
285 285
 }
286 286
 
287 287
 /**
@@ -292,15 +292,15 @@  discard block
 block discarded – undo
292 292
  * @param int $id The ID of the site to display the setting for.
293 293
  */
294 294
 function upload_space_setting( $id ) {
295
-	switch_to_blog( $id );
296
-	$quota = get_option( 'blog_upload_space' );
297
-	restore_current_blog();
295
+    switch_to_blog( $id );
296
+    $quota = get_option( 'blog_upload_space' );
297
+    restore_current_blog();
298 298
 
299
-	if ( ! $quota ) {
300
-		$quota = '';
301
-	}
299
+    if ( ! $quota ) {
300
+        $quota = '';
301
+    }
302 302
 
303
-	?>
303
+    ?>
304 304
 	<tr>
305 305
 		<th><label for="blog-upload-space-number"><?php _e( 'Site Upload Space Quota' ); ?></label></th>
306 306
 		<td>
@@ -320,16 +320,16 @@  discard block
 block discarded – undo
320 320
  * @return int|false The ID of the refreshed user or false if the user does not exist.
321 321
  */
322 322
 function refresh_user_details( $id ) {
323
-	$id = (int) $id;
323
+    $id = (int) $id;
324 324
 
325
-	$user = get_userdata( $id );
326
-	if ( ! $user ) {
327
-		return false;
328
-	}
325
+    $user = get_userdata( $id );
326
+    if ( ! $user ) {
327
+        return false;
328
+    }
329 329
 
330
-	clean_user_cache( $user );
330
+    clean_user_cache( $user );
331 331
 
332
-	return $id;
332
+    return $id;
333 333
 }
334 334
 
335 335
 /**
@@ -342,205 +342,205 @@  discard block
 block discarded – undo
342 342
  *                then the first two letters of $code is returned.
343 343
  */
344 344
 function format_code_lang( $code = '' ) {
345
-	$code       = strtolower( substr( $code, 0, 2 ) );
346
-	$lang_codes = array(
347
-		'aa' => 'Afar',
348
-		'ab' => 'Abkhazian',
349
-		'af' => 'Afrikaans',
350
-		'ak' => 'Akan',
351
-		'sq' => 'Albanian',
352
-		'am' => 'Amharic',
353
-		'ar' => 'Arabic',
354
-		'an' => 'Aragonese',
355
-		'hy' => 'Armenian',
356
-		'as' => 'Assamese',
357
-		'av' => 'Avaric',
358
-		'ae' => 'Avestan',
359
-		'ay' => 'Aymara',
360
-		'az' => 'Azerbaijani',
361
-		'ba' => 'Bashkir',
362
-		'bm' => 'Bambara',
363
-		'eu' => 'Basque',
364
-		'be' => 'Belarusian',
365
-		'bn' => 'Bengali',
366
-		'bh' => 'Bihari',
367
-		'bi' => 'Bislama',
368
-		'bs' => 'Bosnian',
369
-		'br' => 'Breton',
370
-		'bg' => 'Bulgarian',
371
-		'my' => 'Burmese',
372
-		'ca' => 'Catalan; Valencian',
373
-		'ch' => 'Chamorro',
374
-		'ce' => 'Chechen',
375
-		'zh' => 'Chinese',
376
-		'cu' => 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic',
377
-		'cv' => 'Chuvash',
378
-		'kw' => 'Cornish',
379
-		'co' => 'Corsican',
380
-		'cr' => 'Cree',
381
-		'cs' => 'Czech',
382
-		'da' => 'Danish',
383
-		'dv' => 'Divehi; Dhivehi; Maldivian',
384
-		'nl' => 'Dutch; Flemish',
385
-		'dz' => 'Dzongkha',
386
-		'en' => 'English',
387
-		'eo' => 'Esperanto',
388
-		'et' => 'Estonian',
389
-		'ee' => 'Ewe',
390
-		'fo' => 'Faroese',
391
-		'fj' => 'Fijjian',
392
-		'fi' => 'Finnish',
393
-		'fr' => 'French',
394
-		'fy' => 'Western Frisian',
395
-		'ff' => 'Fulah',
396
-		'ka' => 'Georgian',
397
-		'de' => 'German',
398
-		'gd' => 'Gaelic; Scottish Gaelic',
399
-		'ga' => 'Irish',
400
-		'gl' => 'Galician',
401
-		'gv' => 'Manx',
402
-		'el' => 'Greek, Modern',
403
-		'gn' => 'Guarani',
404
-		'gu' => 'Gujarati',
405
-		'ht' => 'Haitian; Haitian Creole',
406
-		'ha' => 'Hausa',
407
-		'he' => 'Hebrew',
408
-		'hz' => 'Herero',
409
-		'hi' => 'Hindi',
410
-		'ho' => 'Hiri Motu',
411
-		'hu' => 'Hungarian',
412
-		'ig' => 'Igbo',
413
-		'is' => 'Icelandic',
414
-		'io' => 'Ido',
415
-		'ii' => 'Sichuan Yi',
416
-		'iu' => 'Inuktitut',
417
-		'ie' => 'Interlingue',
418
-		'ia' => 'Interlingua (International Auxiliary Language Association)',
419
-		'id' => 'Indonesian',
420
-		'ik' => 'Inupiaq',
421
-		'it' => 'Italian',
422
-		'jv' => 'Javanese',
423
-		'ja' => 'Japanese',
424
-		'kl' => 'Kalaallisut; Greenlandic',
425
-		'kn' => 'Kannada',
426
-		'ks' => 'Kashmiri',
427
-		'kr' => 'Kanuri',
428
-		'kk' => 'Kazakh',
429
-		'km' => 'Central Khmer',
430
-		'ki' => 'Kikuyu; Gikuyu',
431
-		'rw' => 'Kinyarwanda',
432
-		'ky' => 'Kirghiz; Kyrgyz',
433
-		'kv' => 'Komi',
434
-		'kg' => 'Kongo',
435
-		'ko' => 'Korean',
436
-		'kj' => 'Kuanyama; Kwanyama',
437
-		'ku' => 'Kurdish',
438
-		'lo' => 'Lao',
439
-		'la' => 'Latin',
440
-		'lv' => 'Latvian',
441
-		'li' => 'Limburgan; Limburger; Limburgish',
442
-		'ln' => 'Lingala',
443
-		'lt' => 'Lithuanian',
444
-		'lb' => 'Luxembourgish; Letzeburgesch',
445
-		'lu' => 'Luba-Katanga',
446
-		'lg' => 'Ganda',
447
-		'mk' => 'Macedonian',
448
-		'mh' => 'Marshallese',
449
-		'ml' => 'Malayalam',
450
-		'mi' => 'Maori',
451
-		'mr' => 'Marathi',
452
-		'ms' => 'Malay',
453
-		'mg' => 'Malagasy',
454
-		'mt' => 'Maltese',
455
-		'mo' => 'Moldavian',
456
-		'mn' => 'Mongolian',
457
-		'na' => 'Nauru',
458
-		'nv' => 'Navajo; Navaho',
459
-		'nr' => 'Ndebele, South; South Ndebele',
460
-		'nd' => 'Ndebele, North; North Ndebele',
461
-		'ng' => 'Ndonga',
462
-		'ne' => 'Nepali',
463
-		'nn' => 'Norwegian Nynorsk; Nynorsk, Norwegian',
464
-		'nb' => 'Bokmål, Norwegian, Norwegian Bokmål',
465
-		'no' => 'Norwegian',
466
-		'ny' => 'Chichewa; Chewa; Nyanja',
467
-		'oc' => 'Occitan, Provençal',
468
-		'oj' => 'Ojibwa',
469
-		'or' => 'Oriya',
470
-		'om' => 'Oromo',
471
-		'os' => 'Ossetian; Ossetic',
472
-		'pa' => 'Panjabi; Punjabi',
473
-		'fa' => 'Persian',
474
-		'pi' => 'Pali',
475
-		'pl' => 'Polish',
476
-		'pt' => 'Portuguese',
477
-		'ps' => 'Pushto',
478
-		'qu' => 'Quechua',
479
-		'rm' => 'Romansh',
480
-		'ro' => 'Romanian',
481
-		'rn' => 'Rundi',
482
-		'ru' => 'Russian',
483
-		'sg' => 'Sango',
484
-		'sa' => 'Sanskrit',
485
-		'sr' => 'Serbian',
486
-		'hr' => 'Croatian',
487
-		'si' => 'Sinhala; Sinhalese',
488
-		'sk' => 'Slovak',
489
-		'sl' => 'Slovenian',
490
-		'se' => 'Northern Sami',
491
-		'sm' => 'Samoan',
492
-		'sn' => 'Shona',
493
-		'sd' => 'Sindhi',
494
-		'so' => 'Somali',
495
-		'st' => 'Sotho, Southern',
496
-		'es' => 'Spanish; Castilian',
497
-		'sc' => 'Sardinian',
498
-		'ss' => 'Swati',
499
-		'su' => 'Sundanese',
500
-		'sw' => 'Swahili',
501
-		'sv' => 'Swedish',
502
-		'ty' => 'Tahitian',
503
-		'ta' => 'Tamil',
504
-		'tt' => 'Tatar',
505
-		'te' => 'Telugu',
506
-		'tg' => 'Tajik',
507
-		'tl' => 'Tagalog',
508
-		'th' => 'Thai',
509
-		'bo' => 'Tibetan',
510
-		'ti' => 'Tigrinya',
511
-		'to' => 'Tonga (Tonga Islands)',
512
-		'tn' => 'Tswana',
513
-		'ts' => 'Tsonga',
514
-		'tk' => 'Turkmen',
515
-		'tr' => 'Turkish',
516
-		'tw' => 'Twi',
517
-		'ug' => 'Uighur; Uyghur',
518
-		'uk' => 'Ukrainian',
519
-		'ur' => 'Urdu',
520
-		'uz' => 'Uzbek',
521
-		've' => 'Venda',
522
-		'vi' => 'Vietnamese',
523
-		'vo' => 'Volapük',
524
-		'cy' => 'Welsh',
525
-		'wa' => 'Walloon',
526
-		'wo' => 'Wolof',
527
-		'xh' => 'Xhosa',
528
-		'yi' => 'Yiddish',
529
-		'yo' => 'Yoruba',
530
-		'za' => 'Zhuang; Chuang',
531
-		'zu' => 'Zulu',
532
-	);
533
-
534
-	/**
535
-	 * Filters the language codes.
536
-	 *
537
-	 * @since MU (3.0.0)
538
-	 *
539
-	 * @param string[] $lang_codes Array of key/value pairs of language codes where key is the short version.
540
-	 * @param string   $code       A two-letter designation of the language.
541
-	 */
542
-	$lang_codes = apply_filters( 'lang_codes', $lang_codes, $code );
543
-	return strtr( $code, $lang_codes );
345
+    $code       = strtolower( substr( $code, 0, 2 ) );
346
+    $lang_codes = array(
347
+        'aa' => 'Afar',
348
+        'ab' => 'Abkhazian',
349
+        'af' => 'Afrikaans',
350
+        'ak' => 'Akan',
351
+        'sq' => 'Albanian',
352
+        'am' => 'Amharic',
353
+        'ar' => 'Arabic',
354
+        'an' => 'Aragonese',
355
+        'hy' => 'Armenian',
356
+        'as' => 'Assamese',
357
+        'av' => 'Avaric',
358
+        'ae' => 'Avestan',
359
+        'ay' => 'Aymara',
360
+        'az' => 'Azerbaijani',
361
+        'ba' => 'Bashkir',
362
+        'bm' => 'Bambara',
363
+        'eu' => 'Basque',
364
+        'be' => 'Belarusian',
365
+        'bn' => 'Bengali',
366
+        'bh' => 'Bihari',
367
+        'bi' => 'Bislama',
368
+        'bs' => 'Bosnian',
369
+        'br' => 'Breton',
370
+        'bg' => 'Bulgarian',
371
+        'my' => 'Burmese',
372
+        'ca' => 'Catalan; Valencian',
373
+        'ch' => 'Chamorro',
374
+        'ce' => 'Chechen',
375
+        'zh' => 'Chinese',
376
+        'cu' => 'Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic',
377
+        'cv' => 'Chuvash',
378
+        'kw' => 'Cornish',
379
+        'co' => 'Corsican',
380
+        'cr' => 'Cree',
381
+        'cs' => 'Czech',
382
+        'da' => 'Danish',
383
+        'dv' => 'Divehi; Dhivehi; Maldivian',
384
+        'nl' => 'Dutch; Flemish',
385
+        'dz' => 'Dzongkha',
386
+        'en' => 'English',
387
+        'eo' => 'Esperanto',
388
+        'et' => 'Estonian',
389
+        'ee' => 'Ewe',
390
+        'fo' => 'Faroese',
391
+        'fj' => 'Fijjian',
392
+        'fi' => 'Finnish',
393
+        'fr' => 'French',
394
+        'fy' => 'Western Frisian',
395
+        'ff' => 'Fulah',
396
+        'ka' => 'Georgian',
397
+        'de' => 'German',
398
+        'gd' => 'Gaelic; Scottish Gaelic',
399
+        'ga' => 'Irish',
400
+        'gl' => 'Galician',
401
+        'gv' => 'Manx',
402
+        'el' => 'Greek, Modern',
403
+        'gn' => 'Guarani',
404
+        'gu' => 'Gujarati',
405
+        'ht' => 'Haitian; Haitian Creole',
406
+        'ha' => 'Hausa',
407
+        'he' => 'Hebrew',
408
+        'hz' => 'Herero',
409
+        'hi' => 'Hindi',
410
+        'ho' => 'Hiri Motu',
411
+        'hu' => 'Hungarian',
412
+        'ig' => 'Igbo',
413
+        'is' => 'Icelandic',
414
+        'io' => 'Ido',
415
+        'ii' => 'Sichuan Yi',
416
+        'iu' => 'Inuktitut',
417
+        'ie' => 'Interlingue',
418
+        'ia' => 'Interlingua (International Auxiliary Language Association)',
419
+        'id' => 'Indonesian',
420
+        'ik' => 'Inupiaq',
421
+        'it' => 'Italian',
422
+        'jv' => 'Javanese',
423
+        'ja' => 'Japanese',
424
+        'kl' => 'Kalaallisut; Greenlandic',
425
+        'kn' => 'Kannada',
426
+        'ks' => 'Kashmiri',
427
+        'kr' => 'Kanuri',
428
+        'kk' => 'Kazakh',
429
+        'km' => 'Central Khmer',
430
+        'ki' => 'Kikuyu; Gikuyu',
431
+        'rw' => 'Kinyarwanda',
432
+        'ky' => 'Kirghiz; Kyrgyz',
433
+        'kv' => 'Komi',
434
+        'kg' => 'Kongo',
435
+        'ko' => 'Korean',
436
+        'kj' => 'Kuanyama; Kwanyama',
437
+        'ku' => 'Kurdish',
438
+        'lo' => 'Lao',
439
+        'la' => 'Latin',
440
+        'lv' => 'Latvian',
441
+        'li' => 'Limburgan; Limburger; Limburgish',
442
+        'ln' => 'Lingala',
443
+        'lt' => 'Lithuanian',
444
+        'lb' => 'Luxembourgish; Letzeburgesch',
445
+        'lu' => 'Luba-Katanga',
446
+        'lg' => 'Ganda',
447
+        'mk' => 'Macedonian',
448
+        'mh' => 'Marshallese',
449
+        'ml' => 'Malayalam',
450
+        'mi' => 'Maori',
451
+        'mr' => 'Marathi',
452
+        'ms' => 'Malay',
453
+        'mg' => 'Malagasy',
454
+        'mt' => 'Maltese',
455
+        'mo' => 'Moldavian',
456
+        'mn' => 'Mongolian',
457
+        'na' => 'Nauru',
458
+        'nv' => 'Navajo; Navaho',
459
+        'nr' => 'Ndebele, South; South Ndebele',
460
+        'nd' => 'Ndebele, North; North Ndebele',
461
+        'ng' => 'Ndonga',
462
+        'ne' => 'Nepali',
463
+        'nn' => 'Norwegian Nynorsk; Nynorsk, Norwegian',
464
+        'nb' => 'Bokmål, Norwegian, Norwegian Bokmål',
465
+        'no' => 'Norwegian',
466
+        'ny' => 'Chichewa; Chewa; Nyanja',
467
+        'oc' => 'Occitan, Provençal',
468
+        'oj' => 'Ojibwa',
469
+        'or' => 'Oriya',
470
+        'om' => 'Oromo',
471
+        'os' => 'Ossetian; Ossetic',
472
+        'pa' => 'Panjabi; Punjabi',
473
+        'fa' => 'Persian',
474
+        'pi' => 'Pali',
475
+        'pl' => 'Polish',
476
+        'pt' => 'Portuguese',
477
+        'ps' => 'Pushto',
478
+        'qu' => 'Quechua',
479
+        'rm' => 'Romansh',
480
+        'ro' => 'Romanian',
481
+        'rn' => 'Rundi',
482
+        'ru' => 'Russian',
483
+        'sg' => 'Sango',
484
+        'sa' => 'Sanskrit',
485
+        'sr' => 'Serbian',
486
+        'hr' => 'Croatian',
487
+        'si' => 'Sinhala; Sinhalese',
488
+        'sk' => 'Slovak',
489
+        'sl' => 'Slovenian',
490
+        'se' => 'Northern Sami',
491
+        'sm' => 'Samoan',
492
+        'sn' => 'Shona',
493
+        'sd' => 'Sindhi',
494
+        'so' => 'Somali',
495
+        'st' => 'Sotho, Southern',
496
+        'es' => 'Spanish; Castilian',
497
+        'sc' => 'Sardinian',
498
+        'ss' => 'Swati',
499
+        'su' => 'Sundanese',
500
+        'sw' => 'Swahili',
501
+        'sv' => 'Swedish',
502
+        'ty' => 'Tahitian',
503
+        'ta' => 'Tamil',
504
+        'tt' => 'Tatar',
505
+        'te' => 'Telugu',
506
+        'tg' => 'Tajik',
507
+        'tl' => 'Tagalog',
508
+        'th' => 'Thai',
509
+        'bo' => 'Tibetan',
510
+        'ti' => 'Tigrinya',
511
+        'to' => 'Tonga (Tonga Islands)',
512
+        'tn' => 'Tswana',
513
+        'ts' => 'Tsonga',
514
+        'tk' => 'Turkmen',
515
+        'tr' => 'Turkish',
516
+        'tw' => 'Twi',
517
+        'ug' => 'Uighur; Uyghur',
518
+        'uk' => 'Ukrainian',
519
+        'ur' => 'Urdu',
520
+        'uz' => 'Uzbek',
521
+        've' => 'Venda',
522
+        'vi' => 'Vietnamese',
523
+        'vo' => 'Volapük',
524
+        'cy' => 'Welsh',
525
+        'wa' => 'Walloon',
526
+        'wo' => 'Wolof',
527
+        'xh' => 'Xhosa',
528
+        'yi' => 'Yiddish',
529
+        'yo' => 'Yoruba',
530
+        'za' => 'Zhuang; Chuang',
531
+        'zu' => 'Zulu',
532
+    );
533
+
534
+    /**
535
+     * Filters the language codes.
536
+     *
537
+     * @since MU (3.0.0)
538
+     *
539
+     * @param string[] $lang_codes Array of key/value pairs of language codes where key is the short version.
540
+     * @param string   $code       A two-letter designation of the language.
541
+     */
542
+    $lang_codes = apply_filters( 'lang_codes', $lang_codes, $code );
543
+    return strtr( $code, $lang_codes );
544 544
 }
545 545
 
546 546
 /**
@@ -556,14 +556,14 @@  discard block
 block discarded – undo
556 556
  *                       if `$taxonomy` is 'category' or 'post_tag'.
557 557
  */
558 558
 function sync_category_tag_slugs( $term, $taxonomy ) {
559
-	if ( global_terms_enabled() && ( 'category' === $taxonomy || 'post_tag' === $taxonomy ) ) {
560
-		if ( is_object( $term ) ) {
561
-			$term->slug = sanitize_title( $term->name );
562
-		} else {
563
-			$term['slug'] = sanitize_title( $term['name'] );
564
-		}
565
-	}
566
-	return $term;
559
+    if ( global_terms_enabled() && ( 'category' === $taxonomy || 'post_tag' === $taxonomy ) ) {
560
+        if ( is_object( $term ) ) {
561
+            $term->slug = sanitize_title( $term->name );
562
+        } else {
563
+            $term['slug'] = sanitize_title( $term['name'] );
564
+        }
565
+    }
566
+    return $term;
567 567
 }
568 568
 
569 569
 /**
@@ -574,50 +574,50 @@  discard block
 block discarded – undo
574 574
  * @access private
575 575
  */
576 576
 function _access_denied_splash() {
577
-	if ( ! is_user_logged_in() || is_network_admin() ) {
578
-		return;
579
-	}
580
-
581
-	$blogs = get_blogs_of_user( get_current_user_id() );
582
-
583
-	if ( wp_list_filter( $blogs, array( 'userblog_id' => get_current_blog_id() ) ) ) {
584
-		return;
585
-	}
586
-
587
-	$blog_name = get_bloginfo( 'name' );
588
-
589
-	if ( empty( $blogs ) ) {
590
-		wp_die(
591
-			sprintf(
592
-				/* translators: 1: Site title. */
593
-				__( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ),
594
-				$blog_name
595
-			),
596
-			403
597
-		);
598
-	}
599
-
600
-	$output = '<p>' . sprintf(
601
-		/* translators: 1: Site title. */
602
-		__( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ),
603
-		$blog_name
604
-	) . '</p>';
605
-	$output .= '<p>' . __( 'If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.' ) . '</p>';
606
-
607
-	$output .= '<h3>' . __( 'Your Sites' ) . '</h3>';
608
-	$output .= '<table>';
609
-
610
-	foreach ( $blogs as $blog ) {
611
-		$output .= '<tr>';
612
-		$output .= "<td>{$blog->blogname}</td>";
613
-		$output .= '<td><a href="' . esc_url( get_admin_url( $blog->userblog_id ) ) . '">' . __( 'Visit Dashboard' ) . '</a> | ' .
614
-			'<a href="' . esc_url( get_home_url( $blog->userblog_id ) ) . '">' . __( 'View Site' ) . '</a></td>';
615
-		$output .= '</tr>';
616
-	}
617
-
618
-	$output .= '</table>';
619
-
620
-	wp_die( $output, 403 );
577
+    if ( ! is_user_logged_in() || is_network_admin() ) {
578
+        return;
579
+    }
580
+
581
+    $blogs = get_blogs_of_user( get_current_user_id() );
582
+
583
+    if ( wp_list_filter( $blogs, array( 'userblog_id' => get_current_blog_id() ) ) ) {
584
+        return;
585
+    }
586
+
587
+    $blog_name = get_bloginfo( 'name' );
588
+
589
+    if ( empty( $blogs ) ) {
590
+        wp_die(
591
+            sprintf(
592
+                /* translators: 1: Site title. */
593
+                __( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ),
594
+                $blog_name
595
+            ),
596
+            403
597
+        );
598
+    }
599
+
600
+    $output = '<p>' . sprintf(
601
+        /* translators: 1: Site title. */
602
+        __( 'You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.' ),
603
+        $blog_name
604
+    ) . '</p>';
605
+    $output .= '<p>' . __( 'If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.' ) . '</p>';
606
+
607
+    $output .= '<h3>' . __( 'Your Sites' ) . '</h3>';
608
+    $output .= '<table>';
609
+
610
+    foreach ( $blogs as $blog ) {
611
+        $output .= '<tr>';
612
+        $output .= "<td>{$blog->blogname}</td>";
613
+        $output .= '<td><a href="' . esc_url( get_admin_url( $blog->userblog_id ) ) . '">' . __( 'Visit Dashboard' ) . '</a> | ' .
614
+            '<a href="' . esc_url( get_home_url( $blog->userblog_id ) ) . '">' . __( 'View Site' ) . '</a></td>';
615
+        $output .= '</tr>';
616
+    }
617
+
618
+    $output .= '</table>';
619
+
620
+    wp_die( $output, 403 );
621 621
 }
622 622
 
623 623
 /**
@@ -629,11 +629,11 @@  discard block
 block discarded – undo
629 629
  * @return bool True if the user has proper permissions, false if they do not.
630 630
  */
631 631
 function check_import_new_users( $permission ) {
632
-	if ( ! current_user_can( 'manage_network_users' ) ) {
633
-		return false;
634
-	}
632
+    if ( ! current_user_can( 'manage_network_users' ) ) {
633
+        return false;
634
+    }
635 635
 
636
-	return true;
636
+    return true;
637 637
 }
638 638
 // See "import_allow_fetch_attachments" and "import_attachment_size_limit" filters too.
639 639
 
@@ -646,45 +646,45 @@  discard block
 block discarded – undo
646 646
  * @param string   $current    Optional. The current language code. Default empty.
647 647
  */
648 648
 function mu_dropdown_languages( $lang_files = array(), $current = '' ) {
649
-	$flag   = false;
650
-	$output = array();
651
-
652
-	foreach ( (array) $lang_files as $val ) {
653
-		$code_lang = basename( $val, '.mo' );
654
-
655
-		if ( 'en_US' === $code_lang ) { // American English.
656
-			$flag          = true;
657
-			$ae            = __( 'American English' );
658
-			$output[ $ae ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $ae . '</option>';
659
-		} elseif ( 'en_GB' === $code_lang ) { // British English.
660
-			$flag          = true;
661
-			$be            = __( 'British English' );
662
-			$output[ $be ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $be . '</option>';
663
-		} else {
664
-			$translated            = format_code_lang( $code_lang );
665
-			$output[ $translated ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . esc_html( $translated ) . '</option>';
666
-		}
667
-	}
668
-
669
-	if ( false === $flag ) { // WordPress English.
670
-		$output[] = '<option value=""' . selected( $current, '', false ) . '>' . __( 'English' ) . '</option>';
671
-	}
672
-
673
-	// Order by name.
674
-	uksort( $output, 'strnatcasecmp' );
675
-
676
-	/**
677
-	 * Filters the languages available in the dropdown.
678
-	 *
679
-	 * @since MU (3.0.0)
680
-	 *
681
-	 * @param string[] $output     Array of HTML output for the dropdown.
682
-	 * @param string[] $lang_files Array of available language files.
683
-	 * @param string   $current    The current language code.
684
-	 */
685
-	$output = apply_filters( 'mu_dropdown_languages', $output, $lang_files, $current );
686
-
687
-	echo implode( "\n\t", $output );
649
+    $flag   = false;
650
+    $output = array();
651
+
652
+    foreach ( (array) $lang_files as $val ) {
653
+        $code_lang = basename( $val, '.mo' );
654
+
655
+        if ( 'en_US' === $code_lang ) { // American English.
656
+            $flag          = true;
657
+            $ae            = __( 'American English' );
658
+            $output[ $ae ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $ae . '</option>';
659
+        } elseif ( 'en_GB' === $code_lang ) { // British English.
660
+            $flag          = true;
661
+            $be            = __( 'British English' );
662
+            $output[ $be ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . $be . '</option>';
663
+        } else {
664
+            $translated            = format_code_lang( $code_lang );
665
+            $output[ $translated ] = '<option value="' . esc_attr( $code_lang ) . '"' . selected( $current, $code_lang, false ) . '> ' . esc_html( $translated ) . '</option>';
666
+        }
667
+    }
668
+
669
+    if ( false === $flag ) { // WordPress English.
670
+        $output[] = '<option value=""' . selected( $current, '', false ) . '>' . __( 'English' ) . '</option>';
671
+    }
672
+
673
+    // Order by name.
674
+    uksort( $output, 'strnatcasecmp' );
675
+
676
+    /**
677
+     * Filters the languages available in the dropdown.
678
+     *
679
+     * @since MU (3.0.0)
680
+     *
681
+     * @param string[] $output     Array of HTML output for the dropdown.
682
+     * @param string[] $lang_files Array of available language files.
683
+     * @param string   $current    The current language code.
684
+     */
685
+    $output = apply_filters( 'mu_dropdown_languages', $output, $lang_files, $current );
686
+
687
+    echo implode( "\n\t", $output );
688 688
 }
689 689
 
690 690
 /**
@@ -698,23 +698,23 @@  discard block
 block discarded – undo
698 698
  * @return void|false Void on success. False if the current user is not a super admin.
699 699
  */
700 700
 function site_admin_notice() {
701
-	global $wp_db_version, $pagenow;
702
-
703
-	if ( ! current_user_can( 'upgrade_network' ) ) {
704
-		return false;
705
-	}
706
-
707
-	if ( 'upgrade.php' === $pagenow ) {
708
-		return;
709
-	}
710
-
711
-	if ( (int) get_site_option( 'wpmu_upgrade_site' ) !== $wp_db_version ) {
712
-		echo "<div class='update-nag notice notice-warning inline'>" . sprintf(
713
-			/* translators: %s: URL to Upgrade Network screen. */
714
-			__( 'Thank you for Updating! Please visit the <a href="%s">Upgrade Network</a> page to update all your sites.' ),
715
-			esc_url( network_admin_url( 'upgrade.php' ) )
716
-		) . '</div>';
717
-	}
701
+    global $wp_db_version, $pagenow;
702
+
703
+    if ( ! current_user_can( 'upgrade_network' ) ) {
704
+        return false;
705
+    }
706
+
707
+    if ( 'upgrade.php' === $pagenow ) {
708
+        return;
709
+    }
710
+
711
+    if ( (int) get_site_option( 'wpmu_upgrade_site' ) !== $wp_db_version ) {
712
+        echo "<div class='update-nag notice notice-warning inline'>" . sprintf(
713
+            /* translators: %s: URL to Upgrade Network screen. */
714
+            __( 'Thank you for Updating! Please visit the <a href="%s">Upgrade Network</a> page to update all your sites.' ),
715
+            esc_url( network_admin_url( 'upgrade.php' ) )
716
+        ) . '</div>';
717
+    }
718 718
 }
719 719
 
720 720
 /**
@@ -730,35 +730,35 @@  discard block
 block discarded – undo
730 730
  * @return array The new array of post data after checking for collisions.
731 731
  */
732 732
 function avoid_blog_page_permalink_collision( $data, $postarr ) {
733
-	if ( is_subdomain_install() ) {
734
-		return $data;
735
-	}
736
-	if ( 'page' !== $data['post_type'] ) {
737
-		return $data;
738
-	}
739
-	if ( ! isset( $data['post_name'] ) || '' === $data['post_name'] ) {
740
-		return $data;
741
-	}
742
-	if ( ! is_main_site() ) {
743
-		return $data;
744
-	}
745
-	if ( isset( $data['post_parent'] ) && $data['post_parent'] ) {
746
-		return $data;
747
-	}
748
-
749
-	$post_name = $data['post_name'];
750
-	$c         = 0;
751
-
752
-	while ( $c < 10 && get_id_from_blogname( $post_name ) ) {
753
-		$post_name .= mt_rand( 1, 10 );
754
-		$c++;
755
-	}
756
-
757
-	if ( $post_name !== $data['post_name'] ) {
758
-		$data['post_name'] = $post_name;
759
-	}
760
-
761
-	return $data;
733
+    if ( is_subdomain_install() ) {
734
+        return $data;
735
+    }
736
+    if ( 'page' !== $data['post_type'] ) {
737
+        return $data;
738
+    }
739
+    if ( ! isset( $data['post_name'] ) || '' === $data['post_name'] ) {
740
+        return $data;
741
+    }
742
+    if ( ! is_main_site() ) {
743
+        return $data;
744
+    }
745
+    if ( isset( $data['post_parent'] ) && $data['post_parent'] ) {
746
+        return $data;
747
+    }
748
+
749
+    $post_name = $data['post_name'];
750
+    $c         = 0;
751
+
752
+    while ( $c < 10 && get_id_from_blogname( $post_name ) ) {
753
+        $post_name .= mt_rand( 1, 10 );
754
+        $c++;
755
+    }
756
+
757
+    if ( $post_name !== $data['post_name'] ) {
758
+        $data['post_name'] = $post_name;
759
+    }
760
+
761
+    return $data;
762 762
 }
763 763
 
764 764
 /**
@@ -770,45 +770,45 @@  discard block
 block discarded – undo
770 770
  * @since 3.0.0
771 771
  */
772 772
 function choose_primary_blog() {
773
-	?>
773
+    ?>
774 774
 	<table class="form-table" role="presentation">
775 775
 	<tr>
776 776
 	<?php /* translators: My Sites label. */ ?>
777 777
 		<th scope="row"><label for="primary_blog"><?php _e( 'Primary Site' ); ?></label></th>
778 778
 		<td>
779 779
 		<?php
780
-		$all_blogs    = get_blogs_of_user( get_current_user_id() );
781
-		$primary_blog = (int) get_user_meta( get_current_user_id(), 'primary_blog', true );
782
-		if ( count( $all_blogs ) > 1 ) {
783
-			$found = false;
784
-			?>
780
+        $all_blogs    = get_blogs_of_user( get_current_user_id() );
781
+        $primary_blog = (int) get_user_meta( get_current_user_id(), 'primary_blog', true );
782
+        if ( count( $all_blogs ) > 1 ) {
783
+            $found = false;
784
+            ?>
785 785
 			<select name="primary_blog" id="primary_blog">
786 786
 				<?php
787
-				foreach ( (array) $all_blogs as $blog ) {
788
-					if ( $blog->userblog_id === $primary_blog ) {
789
-						$found = true;
790
-					}
791
-					?>
787
+                foreach ( (array) $all_blogs as $blog ) {
788
+                    if ( $blog->userblog_id === $primary_blog ) {
789
+                        $found = true;
790
+                    }
791
+                    ?>
792 792
 					<option value="<?php echo $blog->userblog_id; ?>"<?php selected( $primary_blog, $blog->userblog_id ); ?>><?php echo esc_url( get_home_url( $blog->userblog_id ) ); ?></option>
793 793
 					<?php
794
-				}
795
-				?>
794
+                }
795
+                ?>
796 796
 			</select>
797 797
 			<?php
798
-			if ( ! $found ) {
799
-				$blog = reset( $all_blogs );
800
-				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
801
-			}
802
-		} elseif ( 1 === count( $all_blogs ) ) {
803
-			$blog = reset( $all_blogs );
804
-			echo esc_url( get_home_url( $blog->userblog_id ) );
805
-			if ( $blog->userblog_id !== $primary_blog ) { // Set the primary blog again if it's out of sync with blog list.
806
-				update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
807
-			}
808
-		} else {
809
-			echo 'N/A';
810
-		}
811
-		?>
798
+            if ( ! $found ) {
799
+                $blog = reset( $all_blogs );
800
+                update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
801
+            }
802
+        } elseif ( 1 === count( $all_blogs ) ) {
803
+            $blog = reset( $all_blogs );
804
+            echo esc_url( get_home_url( $blog->userblog_id ) );
805
+            if ( $blog->userblog_id !== $primary_blog ) { // Set the primary blog again if it's out of sync with blog list.
806
+                update_user_meta( get_current_user_id(), 'primary_blog', $blog->userblog_id );
807
+            }
808
+        } else {
809
+            echo 'N/A';
810
+        }
811
+        ?>
812 812
 		</td>
813 813
 	</tr>
814 814
 	</table>
@@ -827,21 +827,21 @@  discard block
 block discarded – undo
827 827
  * @return bool True if network can be edited, otherwise false.
828 828
  */
829 829
 function can_edit_network( $network_id ) {
830
-	if ( get_current_network_id() === (int) $network_id ) {
831
-		$result = true;
832
-	} else {
833
-		$result = false;
834
-	}
835
-
836
-	/**
837
-	 * Filters whether this network can be edited from this page.
838
-	 *
839
-	 * @since 3.1.0
840
-	 *
841
-	 * @param bool $result     Whether the network can be edited from this page.
842
-	 * @param int  $network_id The network ID to check.
843
-	 */
844
-	return apply_filters( 'can_edit_network', $result, $network_id );
830
+    if ( get_current_network_id() === (int) $network_id ) {
831
+        $result = true;
832
+    } else {
833
+        $result = false;
834
+    }
835
+
836
+    /**
837
+     * Filters whether this network can be edited from this page.
838
+     *
839
+     * @since 3.1.0
840
+     *
841
+     * @param bool $result     Whether the network can be edited from this page.
842
+     * @param int  $network_id The network ID to check.
843
+     */
844
+    return apply_filters( 'can_edit_network', $result, $network_id );
845 845
 }
846 846
 
847 847
 /**
@@ -852,7 +852,7 @@  discard block
 block discarded – undo
852 852
  * @access private
853 853
  */
854 854
 function _thickbox_path_admin_subfolder() {
855
-	?>
855
+    ?>
856 856
 <script type="text/javascript">
857 857
 var tb_pathToImage = "<?php echo esc_js( includes_url( 'js/thickbox/loadingAnimation.gif', 'relative' ) ); ?>";
858 858
 </script>
@@ -863,11 +863,11 @@  discard block
 block discarded – undo
863 863
  * @param array $users
864 864
  */
865 865
 function confirm_delete_users( $users ) {
866
-	$current_user = wp_get_current_user();
867
-	if ( ! is_array( $users ) || empty( $users ) ) {
868
-		return false;
869
-	}
870
-	?>
866
+    $current_user = wp_get_current_user();
867
+    if ( ! is_array( $users ) || empty( $users ) ) {
868
+        return false;
869
+    }
870
+    ?>
871 871
 	<h1><?php esc_html_e( 'Users' ); ?></h1>
872 872
 
873 873
 	<?php if ( 1 === count( $users ) ) : ?>
@@ -879,89 +879,89 @@  discard block
 block discarded – undo
879 879
 	<form action="users.php?action=dodelete" method="post">
880 880
 	<input type="hidden" name="dodelete" />
881 881
 	<?php
882
-	wp_nonce_field( 'ms-users-delete' );
883
-	$site_admins = get_super_admins();
884
-	$admin_out   = '<option value="' . esc_attr( $current_user->ID ) . '">' . $current_user->user_login . '</option>';
885
-	?>
882
+    wp_nonce_field( 'ms-users-delete' );
883
+    $site_admins = get_super_admins();
884
+    $admin_out   = '<option value="' . esc_attr( $current_user->ID ) . '">' . $current_user->user_login . '</option>';
885
+    ?>
886 886
 	<table class="form-table" role="presentation">
887 887
 	<?php
888
-	$allusers = (array) $_POST['allusers'];
889
-	foreach ( $allusers as $user_id ) {
890
-		if ( '' !== $user_id && '0' !== $user_id ) {
891
-			$delete_user = get_userdata( $user_id );
892
-
893
-			if ( ! current_user_can( 'delete_user', $delete_user->ID ) ) {
894
-				wp_die(
895
-					sprintf(
896
-						/* translators: %s: User login. */
897
-						__( 'Warning! User %s cannot be deleted.' ),
898
-						$delete_user->user_login
899
-					)
900
-				);
901
-			}
902
-
903
-			if ( in_array( $delete_user->user_login, $site_admins, true ) ) {
904
-				wp_die(
905
-					sprintf(
906
-						/* translators: %s: User login. */
907
-						__( 'Warning! User cannot be deleted. The user %s is a network administrator.' ),
908
-						'<em>' . $delete_user->user_login . '</em>'
909
-					)
910
-				);
911
-			}
912
-			?>
888
+    $allusers = (array) $_POST['allusers'];
889
+    foreach ( $allusers as $user_id ) {
890
+        if ( '' !== $user_id && '0' !== $user_id ) {
891
+            $delete_user = get_userdata( $user_id );
892
+
893
+            if ( ! current_user_can( 'delete_user', $delete_user->ID ) ) {
894
+                wp_die(
895
+                    sprintf(
896
+                        /* translators: %s: User login. */
897
+                        __( 'Warning! User %s cannot be deleted.' ),
898
+                        $delete_user->user_login
899
+                    )
900
+                );
901
+            }
902
+
903
+            if ( in_array( $delete_user->user_login, $site_admins, true ) ) {
904
+                wp_die(
905
+                    sprintf(
906
+                        /* translators: %s: User login. */
907
+                        __( 'Warning! User cannot be deleted. The user %s is a network administrator.' ),
908
+                        '<em>' . $delete_user->user_login . '</em>'
909
+                    )
910
+                );
911
+            }
912
+            ?>
913 913
 			<tr>
914 914
 				<th scope="row"><?php echo $delete_user->user_login; ?>
915 915
 					<?php echo '<input type="hidden" name="user[]" value="' . esc_attr( $user_id ) . '" />' . "\n"; ?>
916 916
 				</th>
917 917
 			<?php
918
-			$blogs = get_blogs_of_user( $user_id, true );
918
+            $blogs = get_blogs_of_user( $user_id, true );
919 919
 
920
-			if ( ! empty( $blogs ) ) {
921
-				?>
920
+            if ( ! empty( $blogs ) ) {
921
+                ?>
922 922
 				<td><fieldset><p><legend>
923 923
 				<?php
924
-				printf(
925
-					/* translators: %s: User login. */
926
-					__( 'What should be done with content owned by %s?' ),
927
-					'<em>' . $delete_user->user_login . '</em>'
928
-				);
929
-				?>
924
+                printf(
925
+                    /* translators: %s: User login. */
926
+                    __( 'What should be done with content owned by %s?' ),
927
+                    '<em>' . $delete_user->user_login . '</em>'
928
+                );
929
+                ?>
930 930
 				</legend></p>
931 931
 				<?php
932
-				foreach ( (array) $blogs as $key => $details ) {
933
-					$blog_users = get_users(
934
-						array(
935
-							'blog_id' => $details->userblog_id,
936
-							'fields'  => array( 'ID', 'user_login' ),
937
-						)
938
-					);
939
-
940
-					if ( is_array( $blog_users ) && ! empty( $blog_users ) ) {
941
-						$user_site      = "<a href='" . esc_url( get_home_url( $details->userblog_id ) ) . "'>{$details->blogname}</a>";
942
-						$user_dropdown  = '<label for="reassign_user" class="screen-reader-text">' . __( 'Select a user' ) . '</label>';
943
-						$user_dropdown .= "<select name='blog[$user_id][$key]' id='reassign_user'>";
944
-						$user_list      = '';
945
-
946
-						foreach ( $blog_users as $user ) {
947
-							if ( ! in_array( (int) $user->ID, $allusers, true ) ) {
948
-								$user_list .= "<option value='{$user->ID}'>{$user->user_login}</option>";
949
-							}
950
-						}
951
-
952
-						if ( '' === $user_list ) {
953
-							$user_list = $admin_out;
954
-						}
955
-
956
-						$user_dropdown .= $user_list;
957
-						$user_dropdown .= "</select>\n";
958
-						?>
932
+                foreach ( (array) $blogs as $key => $details ) {
933
+                    $blog_users = get_users(
934
+                        array(
935
+                            'blog_id' => $details->userblog_id,
936
+                            'fields'  => array( 'ID', 'user_login' ),
937
+                        )
938
+                    );
939
+
940
+                    if ( is_array( $blog_users ) && ! empty( $blog_users ) ) {
941
+                        $user_site      = "<a href='" . esc_url( get_home_url( $details->userblog_id ) ) . "'>{$details->blogname}</a>";
942
+                        $user_dropdown  = '<label for="reassign_user" class="screen-reader-text">' . __( 'Select a user' ) . '</label>';
943
+                        $user_dropdown .= "<select name='blog[$user_id][$key]' id='reassign_user'>";
944
+                        $user_list      = '';
945
+
946
+                        foreach ( $blog_users as $user ) {
947
+                            if ( ! in_array( (int) $user->ID, $allusers, true ) ) {
948
+                                $user_list .= "<option value='{$user->ID}'>{$user->user_login}</option>";
949
+                            }
950
+                        }
951
+
952
+                        if ( '' === $user_list ) {
953
+                            $user_list = $admin_out;
954
+                        }
955
+
956
+                        $user_dropdown .= $user_list;
957
+                        $user_dropdown .= "</select>\n";
958
+                        ?>
959 959
 						<ul style="list-style:none;">
960 960
 							<li>
961 961
 								<?php
962
-								/* translators: %s: Link to user's site. */
963
-								printf( __( 'Site: %s' ), $user_site );
964
-								?>
962
+                                /* translators: %s: Link to user's site. */
963
+                                printf( __( 'Site: %s' ), $user_site );
964
+                                ?>
965 965
 							</li>
966 966
 							<li><label><input type="radio" id="delete_option0" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="delete" checked="checked" />
967 967
 							<?php _e( 'Delete all content.' ); ?></label></li>
@@ -970,37 +970,37 @@  discard block
 block discarded – undo
970 970
 							<?php echo $user_dropdown; ?></li>
971 971
 						</ul>
972 972
 						<?php
973
-					}
974
-				}
975
-				echo '</fieldset></td></tr>';
976
-			} else {
977
-				?>
973
+                    }
974
+                }
975
+                echo '</fieldset></td></tr>';
976
+            } else {
977
+                ?>
978 978
 				<td><p><?php _e( 'User has no sites or content and will be deleted.' ); ?></p></td>
979 979
 			<?php } ?>
980 980
 			</tr>
981 981
 			<?php
982
-		}
983
-	}
982
+        }
983
+    }
984 984
 
985
-	?>
985
+    ?>
986 986
 	</table>
987 987
 	<?php
988
-	/** This action is documented in wp-admin/users.php */
989
-	do_action( 'delete_user_form', $current_user, $allusers );
988
+    /** This action is documented in wp-admin/users.php */
989
+    do_action( 'delete_user_form', $current_user, $allusers );
990 990
 
991
-	if ( 1 === count( $users ) ) :
992
-		?>
991
+    if ( 1 === count( $users ) ) :
992
+        ?>
993 993
 		<p><?php _e( 'Once you hit &#8220;Confirm Deletion&#8221;, the user will be permanently removed.' ); ?></p>
994 994
 	<?php else : ?>
995 995
 		<p><?php _e( 'Once you hit &#8220;Confirm Deletion&#8221;, these users will be permanently removed.' ); ?></p>
996 996
 		<?php
997
-	endif;
997
+    endif;
998 998
 
999
-	submit_button( __( 'Confirm Deletion' ), 'primary' );
1000
-	?>
999
+    submit_button( __( 'Confirm Deletion' ), 'primary' );
1000
+    ?>
1001 1001
 	</form>
1002 1002
 	<?php
1003
-	return true;
1003
+    return true;
1004 1004
 }
1005 1005
 
1006 1006
 /**
@@ -1009,7 +1009,7 @@  discard block
 block discarded – undo
1009 1009
  * @since 4.1.0
1010 1010
  */
1011 1011
 function network_settings_add_js() {
1012
-	?>
1012
+    ?>
1013 1013
 <script type="text/javascript">
1014 1014
 jQuery( function($) {
1015 1015
 	var languageSelect = $( '#WPLANG' );
@@ -1042,98 +1042,98 @@  discard block
 block discarded – undo
1042 1042
  */
1043 1043
 function network_edit_site_nav( $args = array() ) {
1044 1044
 
1045
-	/**
1046
-	 * Filters the links that appear on site-editing network pages.
1047
-	 *
1048
-	 * Default links: 'site-info', 'site-users', 'site-themes', and 'site-settings'.
1049
-	 *
1050
-	 * @since 4.6.0
1051
-	 *
1052
-	 * @param array $links {
1053
-	 *     An array of link data representing individual network admin pages.
1054
-	 *
1055
-	 *     @type array $link_slug {
1056
-	 *         An array of information about the individual link to a page.
1057
-	 *
1058
-	 *         $type string $label Label to use for the link.
1059
-	 *         $type string $url   URL, relative to `network_admin_url()` to use for the link.
1060
-	 *         $type string $cap   Capability required to see the link.
1061
-	 *     }
1062
-	 * }
1063
-	 */
1064
-	$links = apply_filters(
1065
-		'network_edit_site_nav_links',
1066
-		array(
1067
-			'site-info'     => array(
1068
-				'label' => __( 'Info' ),
1069
-				'url'   => 'site-info.php',
1070
-				'cap'   => 'manage_sites',
1071
-			),
1072
-			'site-users'    => array(
1073
-				'label' => __( 'Users' ),
1074
-				'url'   => 'site-users.php',
1075
-				'cap'   => 'manage_sites',
1076
-			),
1077
-			'site-themes'   => array(
1078
-				'label' => __( 'Themes' ),
1079
-				'url'   => 'site-themes.php',
1080
-				'cap'   => 'manage_sites',
1081
-			),
1082
-			'site-settings' => array(
1083
-				'label' => __( 'Settings' ),
1084
-				'url'   => 'site-settings.php',
1085
-				'cap'   => 'manage_sites',
1086
-			),
1087
-		)
1088
-	);
1089
-
1090
-	// Parse arguments.
1091
-	$parsed_args = wp_parse_args(
1092
-		$args,
1093
-		array(
1094
-			'blog_id'  => isset( $_GET['blog_id'] ) ? (int) $_GET['blog_id'] : 0,
1095
-			'links'    => $links,
1096
-			'selected' => 'site-info',
1097
-		)
1098
-	);
1099
-
1100
-	// Setup the links array.
1101
-	$screen_links = array();
1102
-
1103
-	// Loop through tabs.
1104
-	foreach ( $parsed_args['links'] as $link_id => $link ) {
1105
-
1106
-		// Skip link if user can't access.
1107
-		if ( ! current_user_can( $link['cap'], $parsed_args['blog_id'] ) ) {
1108
-			continue;
1109
-		}
1110
-
1111
-		// Link classes.
1112
-		$classes = array( 'nav-tab' );
1113
-
1114
-		// Aria-current attribute.
1115
-		$aria_current = '';
1116
-
1117
-		// Selected is set by the parent OR assumed by the $pagenow global.
1118
-		if ( $parsed_args['selected'] === $link_id || $link['url'] === $GLOBALS['pagenow'] ) {
1119
-			$classes[]    = 'nav-tab-active';
1120
-			$aria_current = ' aria-current="page"';
1121
-		}
1122
-
1123
-		// Escape each class.
1124
-		$esc_classes = implode( ' ', $classes );
1125
-
1126
-		// Get the URL for this link.
1127
-		$url = add_query_arg( array( 'id' => $parsed_args['blog_id'] ), network_admin_url( $link['url'] ) );
1128
-
1129
-		// Add link to nav links.
1130
-		$screen_links[ $link_id ] = '<a href="' . esc_url( $url ) . '" id="' . esc_attr( $link_id ) . '" class="' . $esc_classes . '"' . $aria_current . '>' . esc_html( $link['label'] ) . '</a>';
1131
-	}
1132
-
1133
-	// All done!
1134
-	echo '<nav class="nav-tab-wrapper wp-clearfix" aria-label="' . esc_attr__( 'Secondary menu' ) . '">';
1135
-	echo implode( '', $screen_links );
1136
-	echo '</nav>';
1045
+    /**
1046
+     * Filters the links that appear on site-editing network pages.
1047
+     *
1048
+     * Default links: 'site-info', 'site-users', 'site-themes', and 'site-settings'.
1049
+     *
1050
+     * @since 4.6.0
1051
+     *
1052
+     * @param array $links {
1053
+     *     An array of link data representing individual network admin pages.
1054
+     *
1055
+     *     @type array $link_slug {
1056
+     *         An array of information about the individual link to a page.
1057
+     *
1058
+     *         $type string $label Label to use for the link.
1059
+     *         $type string $url   URL, relative to `network_admin_url()` to use for the link.
1060
+     *         $type string $cap   Capability required to see the link.
1061
+     *     }
1062
+     * }
1063
+     */
1064
+    $links = apply_filters(
1065
+        'network_edit_site_nav_links',
1066
+        array(
1067
+            'site-info'     => array(
1068
+                'label' => __( 'Info' ),
1069
+                'url'   => 'site-info.php',
1070
+                'cap'   => 'manage_sites',
1071
+            ),
1072
+            'site-users'    => array(
1073
+                'label' => __( 'Users' ),
1074
+                'url'   => 'site-users.php',
1075
+                'cap'   => 'manage_sites',
1076
+            ),
1077
+            'site-themes'   => array(
1078
+                'label' => __( 'Themes' ),
1079
+                'url'   => 'site-themes.php',
1080
+                'cap'   => 'manage_sites',
1081
+            ),
1082
+            'site-settings' => array(
1083
+                'label' => __( 'Settings' ),
1084
+                'url'   => 'site-settings.php',
1085
+                'cap'   => 'manage_sites',
1086
+            ),
1087
+        )
1088
+    );
1089
+
1090
+    // Parse arguments.
1091
+    $parsed_args = wp_parse_args(
1092
+        $args,
1093
+        array(
1094
+            'blog_id'  => isset( $_GET['blog_id'] ) ? (int) $_GET['blog_id'] : 0,
1095
+            'links'    => $links,
1096
+            'selected' => 'site-info',
1097
+        )
1098
+    );
1099
+
1100
+    // Setup the links array.
1101
+    $screen_links = array();
1102
+
1103
+    // Loop through tabs.
1104
+    foreach ( $parsed_args['links'] as $link_id => $link ) {
1105
+
1106
+        // Skip link if user can't access.
1107
+        if ( ! current_user_can( $link['cap'], $parsed_args['blog_id'] ) ) {
1108
+            continue;
1109
+        }
1110
+
1111
+        // Link classes.
1112
+        $classes = array( 'nav-tab' );
1113
+
1114
+        // Aria-current attribute.
1115
+        $aria_current = '';
1116
+
1117
+        // Selected is set by the parent OR assumed by the $pagenow global.
1118
+        if ( $parsed_args['selected'] === $link_id || $link['url'] === $GLOBALS['pagenow'] ) {
1119
+            $classes[]    = 'nav-tab-active';
1120
+            $aria_current = ' aria-current="page"';
1121
+        }
1122
+
1123
+        // Escape each class.
1124
+        $esc_classes = implode( ' ', $classes );
1125
+
1126
+        // Get the URL for this link.
1127
+        $url = add_query_arg( array( 'id' => $parsed_args['blog_id'] ), network_admin_url( $link['url'] ) );
1128
+
1129
+        // Add link to nav links.
1130
+        $screen_links[ $link_id ] = '<a href="' . esc_url( $url ) . '" id="' . esc_attr( $link_id ) . '" class="' . $esc_classes . '"' . $aria_current . '>' . esc_html( $link['label'] ) . '</a>';
1131
+    }
1132
+
1133
+    // All done!
1134
+    echo '<nav class="nav-tab-wrapper wp-clearfix" aria-label="' . esc_attr__( 'Secondary menu' ) . '">';
1135
+    echo implode( '', $screen_links );
1136
+    echo '</nav>';
1137 1137
 }
1138 1138
 
1139 1139
 /**
@@ -1144,20 +1144,20 @@  discard block
 block discarded – undo
1144 1144
  * @return array Help tab arguments.
1145 1145
  */
1146 1146
 function get_site_screen_help_tab_args() {
1147
-	return array(
1148
-		'id'      => 'overview',
1149
-		'title'   => __( 'Overview' ),
1150
-		'content' =>
1151
-			'<p>' . __( 'The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.' ) . '</p>' .
1152
-			'<p>' . __( '<strong>Info</strong> &mdash; The site URL is rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.' ) . '</p>' .
1153
-			'<p>' . __( '<strong>Users</strong> &mdash; This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.' ) . '</p>' .
1154
-			'<p>' . sprintf(
1155
-				/* translators: %s: URL to Network Themes screen. */
1156
-				__( '<strong>Themes</strong> &mdash; This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site&#8217;s Appearance menu. To enable a theme for the entire network, see the <a href="%s">Network Themes</a> screen.' ),
1157
-				network_admin_url( 'themes.php' )
1158
-			) . '</p>' .
1159
-			'<p>' . __( '<strong>Settings</strong> &mdash; This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.' ) . '</p>',
1160
-	);
1147
+    return array(
1148
+        'id'      => 'overview',
1149
+        'title'   => __( 'Overview' ),
1150
+        'content' =>
1151
+            '<p>' . __( 'The menu is for editing information specific to individual sites, particularly if the admin area of a site is unavailable.' ) . '</p>' .
1152
+            '<p>' . __( '<strong>Info</strong> &mdash; The site URL is rarely edited as this can cause the site to not work properly. The Registered date and Last Updated date are displayed. Network admins can mark a site as archived, spam, deleted and mature, to remove from public listings or disable.' ) . '</p>' .
1153
+            '<p>' . __( '<strong>Users</strong> &mdash; This displays the users associated with this site. You can also change their role, reset their password, or remove them from the site. Removing the user from the site does not remove the user from the network.' ) . '</p>' .
1154
+            '<p>' . sprintf(
1155
+                /* translators: %s: URL to Network Themes screen. */
1156
+                __( '<strong>Themes</strong> &mdash; This area shows themes that are not already enabled across the network. Enabling a theme in this menu makes it accessible to this site. It does not activate the theme, but allows it to show in the site&#8217;s Appearance menu. To enable a theme for the entire network, see the <a href="%s">Network Themes</a> screen.' ),
1157
+                network_admin_url( 'themes.php' )
1158
+            ) . '</p>' .
1159
+            '<p>' . __( '<strong>Settings</strong> &mdash; This page shows a list of all settings associated with this site. Some are created by WordPress and others are created by plugins you activate. Note that some fields are grayed out and say Serialized Data. You cannot modify these values due to the way the setting is stored in the database.' ) . '</p>',
1160
+    );
1161 1161
 }
1162 1162
 
1163 1163
 /**
@@ -1168,7 +1168,7 @@  discard block
 block discarded – undo
1168 1168
  * @return string Help sidebar content.
1169 1169
  */
1170 1170
 function get_site_screen_help_sidebar_content() {
1171
-	return '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
1172
-		'<p>' . __( '<a href="https://wordpress.org/support/article/network-admin-sites-screen/">Documentation on Site Management</a>' ) . '</p>' .
1173
-		'<p>' . __( '<a href="https://wordpress.org/support/forum/multisite/">Support Forums</a>' ) . '</p>';
1171
+    return '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
1172
+        '<p>' . __( '<a href="https://wordpress.org/support/article/network-admin-sites-screen/">Documentation on Site Management</a>' ) . '</p>' .
1173
+        '<p>' . __( '<a href="https://wordpress.org/support/forum/multisite/">Support Forums</a>' ) . '</p>';
1174 1174
 }
Please login to merge, or discard this patch.
brighty/wp-admin/includes/revision.php 1 patch
Indentation   +332 added lines, -332 removed lines patch added patch discarded remove patch
@@ -19,144 +19,144 @@  discard block
 block discarded – undo
19 19
  *                     Or, false on failure.
20 20
  */
21 21
 function wp_get_revision_ui_diff( $post, $compare_from, $compare_to ) {
22
-	$post = get_post( $post );
23
-	if ( ! $post ) {
24
-		return false;
25
-	}
26
-
27
-	if ( $compare_from ) {
28
-		$compare_from = get_post( $compare_from );
29
-		if ( ! $compare_from ) {
30
-			return false;
31
-		}
32
-	} else {
33
-		// If we're dealing with the first revision...
34
-		$compare_from = false;
35
-	}
36
-
37
-	$compare_to = get_post( $compare_to );
38
-	if ( ! $compare_to ) {
39
-		return false;
40
-	}
41
-
42
-	// If comparing revisions, make sure we're dealing with the right post parent.
43
-	// The parent post may be a 'revision' when revisions are disabled and we're looking at autosaves.
44
-	if ( $compare_from && $compare_from->post_parent !== $post->ID && $compare_from->ID !== $post->ID ) {
45
-		return false;
46
-	}
47
-	if ( $compare_to->post_parent !== $post->ID && $compare_to->ID !== $post->ID ) {
48
-		return false;
49
-	}
50
-
51
-	if ( $compare_from && strtotime( $compare_from->post_date_gmt ) > strtotime( $compare_to->post_date_gmt ) ) {
52
-		$temp         = $compare_from;
53
-		$compare_from = $compare_to;
54
-		$compare_to   = $temp;
55
-	}
56
-
57
-	// Add default title if title field is empty.
58
-	if ( $compare_from && empty( $compare_from->post_title ) ) {
59
-		$compare_from->post_title = __( '(no title)' );
60
-	}
61
-	if ( empty( $compare_to->post_title ) ) {
62
-		$compare_to->post_title = __( '(no title)' );
63
-	}
64
-
65
-	$return = array();
66
-
67
-	foreach ( _wp_post_revision_fields( $post ) as $field => $name ) {
68
-		/**
69
-		 * Contextually filter a post revision field.
70
-		 *
71
-		 * The dynamic portion of the hook name, `$field`, corresponds to a name of a
72
-		 * field of the revision object.
73
-		 *
74
-		 * Possible hook names include:
75
-		 *
76
-		 *  - `_wp_post_revision_field_post_title`
77
-		 *  - `_wp_post_revision_field_post_content`
78
-		 *  - `_wp_post_revision_field_post_excerpt`
79
-		 *
80
-		 * @since 3.6.0
81
-		 *
82
-		 * @param string  $revision_field The current revision field to compare to or from.
83
-		 * @param string  $field          The current revision field.
84
-		 * @param WP_Post $compare_from   The revision post object to compare to or from.
85
-		 * @param string  $context        The context of whether the current revision is the old
86
-		 *                                or the new one. Values are 'to' or 'from'.
87
-		 */
88
-		$content_from = $compare_from ? apply_filters( "_wp_post_revision_field_{$field}", $compare_from->$field, $field, $compare_from, 'from' ) : '';
89
-
90
-		/** This filter is documented in wp-admin/includes/revision.php */
91
-		$content_to = apply_filters( "_wp_post_revision_field_{$field}", $compare_to->$field, $field, $compare_to, 'to' );
92
-
93
-		$args = array(
94
-			'show_split_view' => true,
95
-			'title_left'      => __( 'Removed' ),
96
-			'title_right'     => __( 'Added' ),
97
-		);
98
-
99
-		/**
100
-		 * Filters revisions text diff options.
101
-		 *
102
-		 * Filters the options passed to wp_text_diff() when viewing a post revision.
103
-		 *
104
-		 * @since 4.1.0
105
-		 *
106
-		 * @param array   $args {
107
-		 *     Associative array of options to pass to wp_text_diff().
108
-		 *
109
-		 *     @type bool $show_split_view True for split view (two columns), false for
110
-		 *                                 un-split view (single column). Default true.
111
-		 * }
112
-		 * @param string  $field        The current revision field.
113
-		 * @param WP_Post $compare_from The revision post to compare from.
114
-		 * @param WP_Post $compare_to   The revision post to compare to.
115
-		 */
116
-		$args = apply_filters( 'revision_text_diff_options', $args, $field, $compare_from, $compare_to );
117
-
118
-		$diff = wp_text_diff( $content_from, $content_to, $args );
119
-
120
-		if ( ! $diff && 'post_title' === $field ) {
121
-			// It's a better user experience to still show the Title, even if it didn't change.
122
-			// No, you didn't see this.
123
-			$diff = '<table class="diff"><colgroup><col class="content diffsplit left"><col class="content diffsplit middle"><col class="content diffsplit right"></colgroup><tbody><tr>';
124
-
125
-			// In split screen mode, show the title before/after side by side.
126
-			if ( true === $args['show_split_view'] ) {
127
-				$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td><td></td><td>' . esc_html( $compare_to->post_title ) . '</td>';
128
-			} else {
129
-				$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td>';
130
-
131
-				// In single column mode, only show the title once if unchanged.
132
-				if ( $compare_from->post_title !== $compare_to->post_title ) {
133
-					$diff .= '</tr><tr><td>' . esc_html( $compare_to->post_title ) . '</td>';
134
-				}
135
-			}
136
-
137
-			$diff .= '</tr></tbody>';
138
-			$diff .= '</table>';
139
-		}
140
-
141
-		if ( $diff ) {
142
-			$return[] = array(
143
-				'id'   => $field,
144
-				'name' => $name,
145
-				'diff' => $diff,
146
-			);
147
-		}
148
-	}
149
-
150
-	/**
151
-	 * Filters the fields displayed in the post revision diff UI.
152
-	 *
153
-	 * @since 4.1.0
154
-	 *
155
-	 * @param array[] $return       Array of revision UI fields. Each item is an array of id, name, and diff.
156
-	 * @param WP_Post $compare_from The revision post to compare from.
157
-	 * @param WP_Post $compare_to   The revision post to compare to.
158
-	 */
159
-	return apply_filters( 'wp_get_revision_ui_diff', $return, $compare_from, $compare_to );
22
+    $post = get_post( $post );
23
+    if ( ! $post ) {
24
+        return false;
25
+    }
26
+
27
+    if ( $compare_from ) {
28
+        $compare_from = get_post( $compare_from );
29
+        if ( ! $compare_from ) {
30
+            return false;
31
+        }
32
+    } else {
33
+        // If we're dealing with the first revision...
34
+        $compare_from = false;
35
+    }
36
+
37
+    $compare_to = get_post( $compare_to );
38
+    if ( ! $compare_to ) {
39
+        return false;
40
+    }
41
+
42
+    // If comparing revisions, make sure we're dealing with the right post parent.
43
+    // The parent post may be a 'revision' when revisions are disabled and we're looking at autosaves.
44
+    if ( $compare_from && $compare_from->post_parent !== $post->ID && $compare_from->ID !== $post->ID ) {
45
+        return false;
46
+    }
47
+    if ( $compare_to->post_parent !== $post->ID && $compare_to->ID !== $post->ID ) {
48
+        return false;
49
+    }
50
+
51
+    if ( $compare_from && strtotime( $compare_from->post_date_gmt ) > strtotime( $compare_to->post_date_gmt ) ) {
52
+        $temp         = $compare_from;
53
+        $compare_from = $compare_to;
54
+        $compare_to   = $temp;
55
+    }
56
+
57
+    // Add default title if title field is empty.
58
+    if ( $compare_from && empty( $compare_from->post_title ) ) {
59
+        $compare_from->post_title = __( '(no title)' );
60
+    }
61
+    if ( empty( $compare_to->post_title ) ) {
62
+        $compare_to->post_title = __( '(no title)' );
63
+    }
64
+
65
+    $return = array();
66
+
67
+    foreach ( _wp_post_revision_fields( $post ) as $field => $name ) {
68
+        /**
69
+         * Contextually filter a post revision field.
70
+         *
71
+         * The dynamic portion of the hook name, `$field`, corresponds to a name of a
72
+         * field of the revision object.
73
+         *
74
+         * Possible hook names include:
75
+         *
76
+         *  - `_wp_post_revision_field_post_title`
77
+         *  - `_wp_post_revision_field_post_content`
78
+         *  - `_wp_post_revision_field_post_excerpt`
79
+         *
80
+         * @since 3.6.0
81
+         *
82
+         * @param string  $revision_field The current revision field to compare to or from.
83
+         * @param string  $field          The current revision field.
84
+         * @param WP_Post $compare_from   The revision post object to compare to or from.
85
+         * @param string  $context        The context of whether the current revision is the old
86
+         *                                or the new one. Values are 'to' or 'from'.
87
+         */
88
+        $content_from = $compare_from ? apply_filters( "_wp_post_revision_field_{$field}", $compare_from->$field, $field, $compare_from, 'from' ) : '';
89
+
90
+        /** This filter is documented in wp-admin/includes/revision.php */
91
+        $content_to = apply_filters( "_wp_post_revision_field_{$field}", $compare_to->$field, $field, $compare_to, 'to' );
92
+
93
+        $args = array(
94
+            'show_split_view' => true,
95
+            'title_left'      => __( 'Removed' ),
96
+            'title_right'     => __( 'Added' ),
97
+        );
98
+
99
+        /**
100
+         * Filters revisions text diff options.
101
+         *
102
+         * Filters the options passed to wp_text_diff() when viewing a post revision.
103
+         *
104
+         * @since 4.1.0
105
+         *
106
+         * @param array   $args {
107
+         *     Associative array of options to pass to wp_text_diff().
108
+         *
109
+         *     @type bool $show_split_view True for split view (two columns), false for
110
+         *                                 un-split view (single column). Default true.
111
+         * }
112
+         * @param string  $field        The current revision field.
113
+         * @param WP_Post $compare_from The revision post to compare from.
114
+         * @param WP_Post $compare_to   The revision post to compare to.
115
+         */
116
+        $args = apply_filters( 'revision_text_diff_options', $args, $field, $compare_from, $compare_to );
117
+
118
+        $diff = wp_text_diff( $content_from, $content_to, $args );
119
+
120
+        if ( ! $diff && 'post_title' === $field ) {
121
+            // It's a better user experience to still show the Title, even if it didn't change.
122
+            // No, you didn't see this.
123
+            $diff = '<table class="diff"><colgroup><col class="content diffsplit left"><col class="content diffsplit middle"><col class="content diffsplit right"></colgroup><tbody><tr>';
124
+
125
+            // In split screen mode, show the title before/after side by side.
126
+            if ( true === $args['show_split_view'] ) {
127
+                $diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td><td></td><td>' . esc_html( $compare_to->post_title ) . '</td>';
128
+            } else {
129
+                $diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td>';
130
+
131
+                // In single column mode, only show the title once if unchanged.
132
+                if ( $compare_from->post_title !== $compare_to->post_title ) {
133
+                    $diff .= '</tr><tr><td>' . esc_html( $compare_to->post_title ) . '</td>';
134
+                }
135
+            }
136
+
137
+            $diff .= '</tr></tbody>';
138
+            $diff .= '</table>';
139
+        }
140
+
141
+        if ( $diff ) {
142
+            $return[] = array(
143
+                'id'   => $field,
144
+                'name' => $name,
145
+                'diff' => $diff,
146
+            );
147
+        }
148
+    }
149
+
150
+    /**
151
+     * Filters the fields displayed in the post revision diff UI.
152
+     *
153
+     * @since 4.1.0
154
+     *
155
+     * @param array[] $return       Array of revision UI fields. Each item is an array of id, name, and diff.
156
+     * @param WP_Post $compare_from The revision post to compare from.
157
+     * @param WP_Post $compare_to   The revision post to compare to.
158
+     */
159
+    return apply_filters( 'wp_get_revision_ui_diff', $return, $compare_from, $compare_to );
160 160
 
161 161
 }
162 162
 
@@ -171,184 +171,184 @@  discard block
 block discarded – undo
171 171
  * @return array An associative array of revision data and related settings.
172 172
  */
173 173
 function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null ) {
174
-	$post    = get_post( $post );
175
-	$authors = array();
176
-	$now_gmt = time();
177
-
178
-	$revisions = wp_get_post_revisions(
179
-		$post->ID,
180
-		array(
181
-			'order'         => 'ASC',
182
-			'check_enabled' => false,
183
-		)
184
-	);
185
-	// If revisions are disabled, we only want autosaves and the current post.
186
-	if ( ! wp_revisions_enabled( $post ) ) {
187
-		foreach ( $revisions as $revision_id => $revision ) {
188
-			if ( ! wp_is_post_autosave( $revision ) ) {
189
-				unset( $revisions[ $revision_id ] );
190
-			}
191
-		}
192
-		$revisions = array( $post->ID => $post ) + $revisions;
193
-	}
194
-
195
-	$show_avatars = get_option( 'show_avatars' );
196
-
197
-	cache_users( wp_list_pluck( $revisions, 'post_author' ) );
198
-
199
-	$can_restore = current_user_can( 'edit_post', $post->ID );
200
-	$current_id  = false;
201
-
202
-	foreach ( $revisions as $revision ) {
203
-		$modified     = strtotime( $revision->post_modified );
204
-		$modified_gmt = strtotime( $revision->post_modified_gmt . ' +0000' );
205
-		if ( $can_restore ) {
206
-			$restore_link = str_replace(
207
-				'&amp;',
208
-				'&',
209
-				wp_nonce_url(
210
-					add_query_arg(
211
-						array(
212
-							'revision' => $revision->ID,
213
-							'action'   => 'restore',
214
-						),
215
-						admin_url( 'revision.php' )
216
-					),
217
-					"restore-post_{$revision->ID}"
218
-				)
219
-			);
220
-		}
221
-
222
-		if ( ! isset( $authors[ $revision->post_author ] ) ) {
223
-			$authors[ $revision->post_author ] = array(
224
-				'id'     => (int) $revision->post_author,
225
-				'avatar' => $show_avatars ? get_avatar( $revision->post_author, 32 ) : '',
226
-				'name'   => get_the_author_meta( 'display_name', $revision->post_author ),
227
-			);
228
-		}
229
-
230
-		$autosave = (bool) wp_is_post_autosave( $revision );
231
-		$current  = ! $autosave && $revision->post_modified_gmt === $post->post_modified_gmt;
232
-		if ( $current && ! empty( $current_id ) ) {
233
-			// If multiple revisions have the same post_modified_gmt, highest ID is current.
234
-			if ( $current_id < $revision->ID ) {
235
-				$revisions[ $current_id ]['current'] = false;
236
-				$current_id                          = $revision->ID;
237
-			} else {
238
-				$current = false;
239
-			}
240
-		} elseif ( $current ) {
241
-			$current_id = $revision->ID;
242
-		}
243
-
244
-		$revisions_data = array(
245
-			'id'         => $revision->ID,
246
-			'title'      => get_the_title( $post->ID ),
247
-			'author'     => $authors[ $revision->post_author ],
248
-			'date'       => date_i18n( __( 'M j, Y @ H:i' ), $modified ),
249
-			'dateShort'  => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), $modified ),
250
-			/* translators: %s: Human-readable time difference. */
251
-			'timeAgo'    => sprintf( __( '%s ago' ), human_time_diff( $modified_gmt, $now_gmt ) ),
252
-			'autosave'   => $autosave,
253
-			'current'    => $current,
254
-			'restoreUrl' => $can_restore ? $restore_link : false,
255
-		);
256
-
257
-		/**
258
-		 * Filters the array of revisions used on the revisions screen.
259
-		 *
260
-		 * @since 4.4.0
261
-		 *
262
-		 * @param array   $revisions_data {
263
-		 *     The bootstrapped data for the revisions screen.
264
-		 *
265
-		 *     @type int        $id         Revision ID.
266
-		 *     @type string     $title      Title for the revision's parent WP_Post object.
267
-		 *     @type int        $author     Revision post author ID.
268
-		 *     @type string     $date       Date the revision was modified.
269
-		 *     @type string     $dateShort  Short-form version of the date the revision was modified.
270
-		 *     @type string     $timeAgo    GMT-aware amount of time ago the revision was modified.
271
-		 *     @type bool       $autosave   Whether the revision is an autosave.
272
-		 *     @type bool       $current    Whether the revision is both not an autosave and the post
273
-		 *                                  modified date matches the revision modified date (GMT-aware).
274
-		 *     @type bool|false $restoreUrl URL if the revision can be restored, false otherwise.
275
-		 * }
276
-		 * @param WP_Post $revision       The revision's WP_Post object.
277
-		 * @param WP_Post $post           The revision's parent WP_Post object.
278
-		 */
279
-		$revisions[ $revision->ID ] = apply_filters( 'wp_prepare_revision_for_js', $revisions_data, $revision, $post );
280
-	}
281
-
282
-	/**
283
-	 * If we only have one revision, the initial revision is missing; This happens
284
-	 * when we have an autsosave and the user has clicked 'View the Autosave'
285
-	 */
286
-	if ( 1 === count( $revisions ) ) {
287
-		$revisions[ $post->ID ] = array(
288
-			'id'         => $post->ID,
289
-			'title'      => get_the_title( $post->ID ),
290
-			'author'     => $authors[ $revision->post_author ],
291
-			'date'       => date_i18n( __( 'M j, Y @ H:i' ), strtotime( $post->post_modified ) ),
292
-			'dateShort'  => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), strtotime( $post->post_modified ) ),
293
-			/* translators: %s: Human-readable time difference. */
294
-			'timeAgo'    => sprintf( __( '%s ago' ), human_time_diff( strtotime( $post->post_modified_gmt ), $now_gmt ) ),
295
-			'autosave'   => false,
296
-			'current'    => true,
297
-			'restoreUrl' => false,
298
-		);
299
-		$current_id             = $post->ID;
300
-	}
301
-
302
-	/*
174
+    $post    = get_post( $post );
175
+    $authors = array();
176
+    $now_gmt = time();
177
+
178
+    $revisions = wp_get_post_revisions(
179
+        $post->ID,
180
+        array(
181
+            'order'         => 'ASC',
182
+            'check_enabled' => false,
183
+        )
184
+    );
185
+    // If revisions are disabled, we only want autosaves and the current post.
186
+    if ( ! wp_revisions_enabled( $post ) ) {
187
+        foreach ( $revisions as $revision_id => $revision ) {
188
+            if ( ! wp_is_post_autosave( $revision ) ) {
189
+                unset( $revisions[ $revision_id ] );
190
+            }
191
+        }
192
+        $revisions = array( $post->ID => $post ) + $revisions;
193
+    }
194
+
195
+    $show_avatars = get_option( 'show_avatars' );
196
+
197
+    cache_users( wp_list_pluck( $revisions, 'post_author' ) );
198
+
199
+    $can_restore = current_user_can( 'edit_post', $post->ID );
200
+    $current_id  = false;
201
+
202
+    foreach ( $revisions as $revision ) {
203
+        $modified     = strtotime( $revision->post_modified );
204
+        $modified_gmt = strtotime( $revision->post_modified_gmt . ' +0000' );
205
+        if ( $can_restore ) {
206
+            $restore_link = str_replace(
207
+                '&amp;',
208
+                '&',
209
+                wp_nonce_url(
210
+                    add_query_arg(
211
+                        array(
212
+                            'revision' => $revision->ID,
213
+                            'action'   => 'restore',
214
+                        ),
215
+                        admin_url( 'revision.php' )
216
+                    ),
217
+                    "restore-post_{$revision->ID}"
218
+                )
219
+            );
220
+        }
221
+
222
+        if ( ! isset( $authors[ $revision->post_author ] ) ) {
223
+            $authors[ $revision->post_author ] = array(
224
+                'id'     => (int) $revision->post_author,
225
+                'avatar' => $show_avatars ? get_avatar( $revision->post_author, 32 ) : '',
226
+                'name'   => get_the_author_meta( 'display_name', $revision->post_author ),
227
+            );
228
+        }
229
+
230
+        $autosave = (bool) wp_is_post_autosave( $revision );
231
+        $current  = ! $autosave && $revision->post_modified_gmt === $post->post_modified_gmt;
232
+        if ( $current && ! empty( $current_id ) ) {
233
+            // If multiple revisions have the same post_modified_gmt, highest ID is current.
234
+            if ( $current_id < $revision->ID ) {
235
+                $revisions[ $current_id ]['current'] = false;
236
+                $current_id                          = $revision->ID;
237
+            } else {
238
+                $current = false;
239
+            }
240
+        } elseif ( $current ) {
241
+            $current_id = $revision->ID;
242
+        }
243
+
244
+        $revisions_data = array(
245
+            'id'         => $revision->ID,
246
+            'title'      => get_the_title( $post->ID ),
247
+            'author'     => $authors[ $revision->post_author ],
248
+            'date'       => date_i18n( __( 'M j, Y @ H:i' ), $modified ),
249
+            'dateShort'  => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), $modified ),
250
+            /* translators: %s: Human-readable time difference. */
251
+            'timeAgo'    => sprintf( __( '%s ago' ), human_time_diff( $modified_gmt, $now_gmt ) ),
252
+            'autosave'   => $autosave,
253
+            'current'    => $current,
254
+            'restoreUrl' => $can_restore ? $restore_link : false,
255
+        );
256
+
257
+        /**
258
+         * Filters the array of revisions used on the revisions screen.
259
+         *
260
+         * @since 4.4.0
261
+         *
262
+         * @param array   $revisions_data {
263
+         *     The bootstrapped data for the revisions screen.
264
+         *
265
+         *     @type int        $id         Revision ID.
266
+         *     @type string     $title      Title for the revision's parent WP_Post object.
267
+         *     @type int        $author     Revision post author ID.
268
+         *     @type string     $date       Date the revision was modified.
269
+         *     @type string     $dateShort  Short-form version of the date the revision was modified.
270
+         *     @type string     $timeAgo    GMT-aware amount of time ago the revision was modified.
271
+         *     @type bool       $autosave   Whether the revision is an autosave.
272
+         *     @type bool       $current    Whether the revision is both not an autosave and the post
273
+         *                                  modified date matches the revision modified date (GMT-aware).
274
+         *     @type bool|false $restoreUrl URL if the revision can be restored, false otherwise.
275
+         * }
276
+         * @param WP_Post $revision       The revision's WP_Post object.
277
+         * @param WP_Post $post           The revision's parent WP_Post object.
278
+         */
279
+        $revisions[ $revision->ID ] = apply_filters( 'wp_prepare_revision_for_js', $revisions_data, $revision, $post );
280
+    }
281
+
282
+    /**
283
+     * If we only have one revision, the initial revision is missing; This happens
284
+     * when we have an autsosave and the user has clicked 'View the Autosave'
285
+     */
286
+    if ( 1 === count( $revisions ) ) {
287
+        $revisions[ $post->ID ] = array(
288
+            'id'         => $post->ID,
289
+            'title'      => get_the_title( $post->ID ),
290
+            'author'     => $authors[ $revision->post_author ],
291
+            'date'       => date_i18n( __( 'M j, Y @ H:i' ), strtotime( $post->post_modified ) ),
292
+            'dateShort'  => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), strtotime( $post->post_modified ) ),
293
+            /* translators: %s: Human-readable time difference. */
294
+            'timeAgo'    => sprintf( __( '%s ago' ), human_time_diff( strtotime( $post->post_modified_gmt ), $now_gmt ) ),
295
+            'autosave'   => false,
296
+            'current'    => true,
297
+            'restoreUrl' => false,
298
+        );
299
+        $current_id             = $post->ID;
300
+    }
301
+
302
+    /*
303 303
 	 * If a post has been saved since the last revision (no revisioned fields
304 304
 	 * were changed), we may not have a "current" revision. Mark the latest
305 305
 	 * revision as "current".
306 306
 	 */
307
-	if ( empty( $current_id ) ) {
308
-		if ( $revisions[ $revision->ID ]['autosave'] ) {
309
-			$revision = end( $revisions );
310
-			while ( $revision['autosave'] ) {
311
-				$revision = prev( $revisions );
312
-			}
313
-			$current_id = $revision['id'];
314
-		} else {
315
-			$current_id = $revision->ID;
316
-		}
317
-		$revisions[ $current_id ]['current'] = true;
318
-	}
319
-
320
-	// Now, grab the initial diff.
321
-	$compare_two_mode = is_numeric( $from );
322
-	if ( ! $compare_two_mode ) {
323
-		$found = array_search( $selected_revision_id, array_keys( $revisions ), true );
324
-		if ( $found ) {
325
-			$from = array_keys( array_slice( $revisions, $found - 1, 1, true ) );
326
-			$from = reset( $from );
327
-		} else {
328
-			$from = 0;
329
-		}
330
-	}
331
-
332
-	$from = absint( $from );
333
-
334
-	$diffs = array(
335
-		array(
336
-			'id'     => $from . ':' . $selected_revision_id,
337
-			'fields' => wp_get_revision_ui_diff( $post->ID, $from, $selected_revision_id ),
338
-		),
339
-	);
340
-
341
-	return array(
342
-		'postId'         => $post->ID,
343
-		'nonce'          => wp_create_nonce( 'revisions-ajax-nonce' ),
344
-		'revisionData'   => array_values( $revisions ),
345
-		'to'             => $selected_revision_id,
346
-		'from'           => $from,
347
-		'diffData'       => $diffs,
348
-		'baseUrl'        => parse_url( admin_url( 'revision.php' ), PHP_URL_PATH ),
349
-		'compareTwoMode' => absint( $compare_two_mode ), // Apparently booleans are not allowed.
350
-		'revisionIds'    => array_keys( $revisions ),
351
-	);
307
+    if ( empty( $current_id ) ) {
308
+        if ( $revisions[ $revision->ID ]['autosave'] ) {
309
+            $revision = end( $revisions );
310
+            while ( $revision['autosave'] ) {
311
+                $revision = prev( $revisions );
312
+            }
313
+            $current_id = $revision['id'];
314
+        } else {
315
+            $current_id = $revision->ID;
316
+        }
317
+        $revisions[ $current_id ]['current'] = true;
318
+    }
319
+
320
+    // Now, grab the initial diff.
321
+    $compare_two_mode = is_numeric( $from );
322
+    if ( ! $compare_two_mode ) {
323
+        $found = array_search( $selected_revision_id, array_keys( $revisions ), true );
324
+        if ( $found ) {
325
+            $from = array_keys( array_slice( $revisions, $found - 1, 1, true ) );
326
+            $from = reset( $from );
327
+        } else {
328
+            $from = 0;
329
+        }
330
+    }
331
+
332
+    $from = absint( $from );
333
+
334
+    $diffs = array(
335
+        array(
336
+            'id'     => $from . ':' . $selected_revision_id,
337
+            'fields' => wp_get_revision_ui_diff( $post->ID, $from, $selected_revision_id ),
338
+        ),
339
+    );
340
+
341
+    return array(
342
+        'postId'         => $post->ID,
343
+        'nonce'          => wp_create_nonce( 'revisions-ajax-nonce' ),
344
+        'revisionData'   => array_values( $revisions ),
345
+        'to'             => $selected_revision_id,
346
+        'from'           => $from,
347
+        'diffData'       => $diffs,
348
+        'baseUrl'        => parse_url( admin_url( 'revision.php' ), PHP_URL_PATH ),
349
+        'compareTwoMode' => absint( $compare_two_mode ), // Apparently booleans are not allowed.
350
+        'revisionIds'    => array_keys( $revisions ),
351
+    );
352 352
 }
353 353
 
354 354
 /**
@@ -359,8 +359,8 @@  discard block
 block discarded – undo
359 359
  * @global WP_Post $post Global post object.
360 360
  */
361 361
 function wp_print_revision_templates() {
362
-	global $post;
363
-	?><script id="tmpl-revisions-frame" type="text/html">
362
+    global $post;
363
+    ?><script id="tmpl-revisions-frame" type="text/html">
364 364
 		<div class="revisions-control-frame"></div>
365 365
 		<div class="revisions-diff-frame"></div>
366 366
 	</script>
@@ -404,32 +404,32 @@  discard block
 block discarded – undo
404 404
 					<# if ( data.attributes.autosave ) { #>
405 405
 						<span class="byline">
406 406
 						<?php
407
-						printf(
408
-							/* translators: %s: User's display name. */
409
-							__( 'Autosave by %s' ),
410
-							'<span class="author-name">{{ data.attributes.author.name }}</span>'
411
-						);
412
-						?>
407
+                        printf(
408
+                            /* translators: %s: User's display name. */
409
+                            __( 'Autosave by %s' ),
410
+                            '<span class="author-name">{{ data.attributes.author.name }}</span>'
411
+                        );
412
+                        ?>
413 413
 							</span>
414 414
 					<# } else if ( data.attributes.current ) { #>
415 415
 						<span class="byline">
416 416
 						<?php
417
-						printf(
418
-							/* translators: %s: User's display name. */
419
-							__( 'Current Revision by %s' ),
420
-							'<span class="author-name">{{ data.attributes.author.name }}</span>'
421
-						);
422
-						?>
417
+                        printf(
418
+                            /* translators: %s: User's display name. */
419
+                            __( 'Current Revision by %s' ),
420
+                            '<span class="author-name">{{ data.attributes.author.name }}</span>'
421
+                        );
422
+                        ?>
423 423
 							</span>
424 424
 					<# } else { #>
425 425
 						<span class="byline">
426 426
 						<?php
427
-						printf(
428
-							/* translators: %s: User's display name. */
429
-							__( 'Revision by %s' ),
430
-							'<span class="author-name">{{ data.attributes.author.name }}</span>'
431
-						);
432
-						?>
427
+                        printf(
428
+                            /* translators: %s: User's display name. */
429
+                            __( 'Revision by %s' ),
430
+                            '<span class="author-name">{{ data.attributes.author.name }}</span>'
431
+                        );
432
+                        ?>
433 433
 							</span>
434 434
 					<# } #>
435 435
 						<span class="time-ago">{{ data.attributes.timeAgo }}</span>
Please login to merge, or discard this patch.
brighty/wp-admin/includes/class-wp-site-health.php 1 patch
Indentation   +2828 added lines, -2828 removed lines patch added patch discarded remove patch
@@ -8,2673 +8,2673 @@  discard block
 block discarded – undo
8 8
  */
9 9
 
10 10
 class WP_Site_Health {
11
-	private static $instance = null;
12
-
13
-	private $mysql_min_version_check;
14
-	private $mysql_rec_version_check;
15
-
16
-	public $is_mariadb                           = false;
17
-	private $mysql_server_version                = '';
18
-	private $health_check_mysql_required_version = '5.5';
19
-	private $health_check_mysql_rec_version      = '';
20
-
21
-	public $php_memory_limit;
22
-
23
-	public $schedules;
24
-	public $crons;
25
-	public $last_missed_cron     = null;
26
-	public $last_late_cron       = null;
27
-	private $timeout_missed_cron = null;
28
-	private $timeout_late_cron   = null;
29
-
30
-	/**
31
-	 * WP_Site_Health constructor.
32
-	 *
33
-	 * @since 5.2.0
34
-	 */
35
-	public function __construct() {
36
-		$this->maybe_create_scheduled_event();
37
-
38
-		// Save memory limit before it's affected by wp_raise_memory_limit( 'admin' ).
39
-		$this->php_memory_limit = ini_get( 'memory_limit' );
40
-
41
-		$this->timeout_late_cron   = 0;
42
-		$this->timeout_missed_cron = - 5 * MINUTE_IN_SECONDS;
43
-
44
-		if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
45
-			$this->timeout_late_cron   = - 15 * MINUTE_IN_SECONDS;
46
-			$this->timeout_missed_cron = - 1 * HOUR_IN_SECONDS;
47
-		}
48
-
49
-		add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
50
-
51
-		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
52
-		add_action( 'wp_site_health_scheduled_check', array( $this, 'wp_cron_scheduled_check' ) );
53
-
54
-		add_action( 'site_health_tab_content', array( $this, 'show_site_health_tab' ) );
55
-	}
56
-
57
-	/**
58
-	 * Output the content of a tab in the Site Health screen.
59
-	 *
60
-	 * @since 5.8.0
61
-	 *
62
-	 * @param string $tab Slug of the current tab being displayed.
63
-	 */
64
-	public function show_site_health_tab( $tab ) {
65
-		if ( 'debug' === $tab ) {
66
-			require_once ABSPATH . '/wp-admin/site-health-info.php';
67
-		}
68
-	}
69
-
70
-	/**
71
-	 * Return an instance of the WP_Site_Health class, or create one if none exist yet.
72
-	 *
73
-	 * @since 5.4.0
74
-	 *
75
-	 * @return WP_Site_Health|null
76
-	 */
77
-	public static function get_instance() {
78
-		if ( null === self::$instance ) {
79
-			self::$instance = new WP_Site_Health();
80
-		}
81
-
82
-		return self::$instance;
83
-	}
84
-
85
-	/**
86
-	 * Enqueues the site health scripts.
87
-	 *
88
-	 * @since 5.2.0
89
-	 */
90
-	public function enqueue_scripts() {
91
-		$screen = get_current_screen();
92
-		if ( 'site-health' !== $screen->id && 'dashboard' !== $screen->id ) {
93
-			return;
94
-		}
95
-
96
-		$health_check_js_variables = array(
97
-			'screen'      => $screen->id,
98
-			'nonce'       => array(
99
-				'site_status'        => wp_create_nonce( 'health-check-site-status' ),
100
-				'site_status_result' => wp_create_nonce( 'health-check-site-status-result' ),
101
-			),
102
-			'site_status' => array(
103
-				'direct' => array(),
104
-				'async'  => array(),
105
-				'issues' => array(
106
-					'good'        => 0,
107
-					'recommended' => 0,
108
-					'critical'    => 0,
109
-				),
110
-			),
111
-		);
112
-
113
-		$issue_counts = get_transient( 'health-check-site-status-result' );
114
-
115
-		if ( false !== $issue_counts ) {
116
-			$issue_counts = json_decode( $issue_counts );
117
-
118
-			$health_check_js_variables['site_status']['issues'] = $issue_counts;
119
-		}
120
-
121
-		if ( 'site-health' === $screen->id && ( ! isset( $_GET['tab'] ) || empty( $_GET['tab'] ) ) ) {
122
-			$tests = WP_Site_Health::get_tests();
123
-
124
-			// Don't run https test on development environments.
125
-			if ( $this->is_development_environment() ) {
126
-				unset( $tests['async']['https_status'] );
127
-			}
128
-
129
-			foreach ( $tests['direct'] as $test ) {
130
-				if ( is_string( $test['test'] ) ) {
131
-					$test_function = sprintf(
132
-						'get_test_%s',
133
-						$test['test']
134
-					);
135
-
136
-					if ( method_exists( $this, $test_function ) && is_callable( array( $this, $test_function ) ) ) {
137
-						$health_check_js_variables['site_status']['direct'][] = $this->perform_test( array( $this, $test_function ) );
138
-						continue;
139
-					}
140
-				}
141
-
142
-				if ( is_callable( $test['test'] ) ) {
143
-					$health_check_js_variables['site_status']['direct'][] = $this->perform_test( $test['test'] );
144
-				}
145
-			}
146
-
147
-			foreach ( $tests['async'] as $test ) {
148
-				if ( is_string( $test['test'] ) ) {
149
-					$health_check_js_variables['site_status']['async'][] = array(
150
-						'test'      => $test['test'],
151
-						'has_rest'  => ( isset( $test['has_rest'] ) ? $test['has_rest'] : false ),
152
-						'completed' => false,
153
-						'headers'   => isset( $test['headers'] ) ? $test['headers'] : array(),
154
-					);
155
-				}
156
-			}
157
-		}
158
-
159
-		wp_localize_script( 'site-health', 'SiteHealth', $health_check_js_variables );
160
-	}
161
-
162
-	/**
163
-	 * Run a Site Health test directly.
164
-	 *
165
-	 * @since 5.4.0
166
-	 *
167
-	 * @param callable $callback
168
-	 * @return mixed|void
169
-	 */
170
-	private function perform_test( $callback ) {
171
-		/**
172
-		 * Filters the output of a finished Site Health test.
173
-		 *
174
-		 * @since 5.3.0
175
-		 *
176
-		 * @param array $test_result {
177
-		 *     An associative array of test result data.
178
-		 *
179
-		 *     @type string $label       A label describing the test, and is used as a header in the output.
180
-		 *     @type string $status      The status of the test, which can be a value of `good`, `recommended` or `critical`.
181
-		 *     @type array  $badge {
182
-		 *         Tests are put into categories which have an associated badge shown, these can be modified and assigned here.
183
-		 *
184
-		 *         @type string $label The test label, for example `Performance`.
185
-		 *         @type string $color Default `blue`. A string representing a color to use for the label.
186
-		 *     }
187
-		 *     @type string $description A more descriptive explanation of what the test looks for, and why it is important for the end user.
188
-		 *     @type string $actions     An action to direct the user to where they can resolve the issue, if one exists.
189
-		 *     @type string $test        The name of the test being ran, used as a reference point.
190
-		 * }
191
-		 */
192
-		return apply_filters( 'site_status_test_result', call_user_func( $callback ) );
193
-	}
194
-
195
-	/**
196
-	 * Run the SQL version checks.
197
-	 *
198
-	 * These values are used in later tests, but the part of preparing them is more easily managed
199
-	 * early in the class for ease of access and discovery.
200
-	 *
201
-	 * @since 5.2.0
202
-	 *
203
-	 * @global wpdb $wpdb WordPress database abstraction object.
204
-	 */
205
-	private function prepare_sql_data() {
206
-		global $wpdb;
207
-
208
-		if ( $wpdb->use_mysqli ) {
209
-			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
210
-			$mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
211
-		} else {
212
-			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
213
-			$mysql_server_type = mysql_get_server_info( $wpdb->dbh );
214
-		}
215
-
216
-		$this->mysql_server_version = $wpdb->get_var( 'SELECT VERSION()' );
217
-
218
-		$this->health_check_mysql_rec_version = '5.6';
219
-
220
-		if ( stristr( $mysql_server_type, 'mariadb' ) ) {
221
-			$this->is_mariadb                     = true;
222
-			$this->health_check_mysql_rec_version = '10.0';
223
-		}
224
-
225
-		$this->mysql_min_version_check = version_compare( '5.5', $this->mysql_server_version, '<=' );
226
-		$this->mysql_rec_version_check = version_compare( $this->health_check_mysql_rec_version, $this->mysql_server_version, '<=' );
227
-	}
228
-
229
-	/**
230
-	 * Test if `wp_version_check` is blocked.
231
-	 *
232
-	 * It's possible to block updates with the `wp_version_check` filter, but this can't be checked
233
-	 * during an Ajax call, as the filter is never introduced then.
234
-	 *
235
-	 * This filter overrides a standard page request if it's made by an admin through the Ajax call
236
-	 * with the right query argument to check for this.
237
-	 *
238
-	 * @since 5.2.0
239
-	 */
240
-	public function check_wp_version_check_exists() {
241
-		if ( ! is_admin() || ! is_user_logged_in() || ! current_user_can( 'update_core' ) || ! isset( $_GET['health-check-test-wp_version_check'] ) ) {
242
-			return;
243
-		}
244
-
245
-		echo ( has_filter( 'wp_version_check', 'wp_version_check' ) ? 'yes' : 'no' );
246
-
247
-		die();
248
-	}
249
-
250
-	/**
251
-	 * Tests for WordPress version and outputs it.
252
-	 *
253
-	 * Gives various results depending on what kind of updates are available, if any, to encourage
254
-	 * the user to install security updates as a priority.
255
-	 *
256
-	 * @since 5.2.0
257
-	 *
258
-	 * @return array The test result.
259
-	 */
260
-	public function get_test_wordpress_version() {
261
-		$result = array(
262
-			'label'       => '',
263
-			'status'      => '',
264
-			'badge'       => array(
265
-				'label' => __( 'Performance' ),
266
-				'color' => 'blue',
267
-			),
268
-			'description' => '',
269
-			'actions'     => '',
270
-			'test'        => 'wordpress_version',
271
-		);
272
-
273
-		$core_current_version = get_bloginfo( 'version' );
274
-		$core_updates         = get_core_updates();
275
-
276
-		if ( ! is_array( $core_updates ) ) {
277
-			$result['status'] = 'recommended';
278
-
279
-			$result['label'] = sprintf(
280
-				/* translators: %s: Your current version of WordPress. */
281
-				__( 'WordPress version %s' ),
282
-				$core_current_version
283
-			);
284
-
285
-			$result['description'] = sprintf(
286
-				'<p>%s</p>',
287
-				__( 'Unable to check if any new versions of WordPress are available.' )
288
-			);
289
-
290
-			$result['actions'] = sprintf(
291
-				'<a href="%s">%s</a>',
292
-				esc_url( admin_url( 'update-core.php?force-check=1' ) ),
293
-				__( 'Check for updates manually' )
294
-			);
295
-		} else {
296
-			foreach ( $core_updates as $core => $update ) {
297
-				if ( 'upgrade' === $update->response ) {
298
-					$current_version = explode( '.', $core_current_version );
299
-					$new_version     = explode( '.', $update->version );
300
-
301
-					$current_major = $current_version[0] . '.' . $current_version[1];
302
-					$new_major     = $new_version[0] . '.' . $new_version[1];
303
-
304
-					$result['label'] = sprintf(
305
-						/* translators: %s: The latest version of WordPress available. */
306
-						__( 'WordPress update available (%s)' ),
307
-						$update->version
308
-					);
309
-
310
-					$result['actions'] = sprintf(
311
-						'<a href="%s">%s</a>',
312
-						esc_url( admin_url( 'update-core.php' ) ),
313
-						__( 'Install the latest version of WordPress' )
314
-					);
315
-
316
-					if ( $current_major !== $new_major ) {
317
-						// This is a major version mismatch.
318
-						$result['status']      = 'recommended';
319
-						$result['description'] = sprintf(
320
-							'<p>%s</p>',
321
-							__( 'A new version of WordPress is available.' )
322
-						);
323
-					} else {
324
-						// This is a minor version, sometimes considered more critical.
325
-						$result['status']         = 'critical';
326
-						$result['badge']['label'] = __( 'Security' );
327
-						$result['description']    = sprintf(
328
-							'<p>%s</p>',
329
-							__( 'A new minor update is available for your site. Because minor updates often address security, it&#8217;s important to install them.' )
330
-						);
331
-					}
332
-				} else {
333
-					$result['status'] = 'good';
334
-					$result['label']  = sprintf(
335
-						/* translators: %s: The current version of WordPress installed on this site. */
336
-						__( 'Your version of WordPress (%s) is up to date' ),
337
-						$core_current_version
338
-					);
339
-
340
-					$result['description'] = sprintf(
341
-						'<p>%s</p>',
342
-						__( 'You are currently running the latest version of WordPress available, keep it up!' )
343
-					);
344
-				}
345
-			}
346
-		}
347
-
348
-		return $result;
349
-	}
350
-
351
-	/**
352
-	 * Test if plugins are outdated, or unnecessary.
353
-	 *
354
-	 * The tests checks if your plugins are up to date, and encourages you to remove any
355
-	 * that are not in use.
356
-	 *
357
-	 * @since 5.2.0
358
-	 *
359
-	 * @return array The test result.
360
-	 */
361
-	public function get_test_plugin_version() {
362
-		$result = array(
363
-			'label'       => __( 'Your plugins are all up to date' ),
364
-			'status'      => 'good',
365
-			'badge'       => array(
366
-				'label' => __( 'Security' ),
367
-				'color' => 'blue',
368
-			),
369
-			'description' => sprintf(
370
-				'<p>%s</p>',
371
-				__( 'Plugins extend your site&#8217;s functionality with things like contact forms, ecommerce and much more. That means they have deep access to your site, so it&#8217;s vital to keep them up to date.' )
372
-			),
373
-			'actions'     => sprintf(
374
-				'<p><a href="%s">%s</a></p>',
375
-				esc_url( admin_url( 'plugins.php' ) ),
376
-				__( 'Manage your plugins' )
377
-			),
378
-			'test'        => 'plugin_version',
379
-		);
380
-
381
-		$plugins        = get_plugins();
382
-		$plugin_updates = get_plugin_updates();
383
-
384
-		$plugins_have_updates = false;
385
-		$plugins_active       = 0;
386
-		$plugins_total        = 0;
387
-		$plugins_need_update  = 0;
388
-
389
-		// Loop over the available plugins and check their versions and active state.
390
-		foreach ( $plugins as $plugin_path => $plugin ) {
391
-			$plugins_total++;
392
-
393
-			if ( is_plugin_active( $plugin_path ) ) {
394
-				$plugins_active++;
395
-			}
396
-
397
-			$plugin_version = $plugin['Version'];
398
-
399
-			if ( array_key_exists( $plugin_path, $plugin_updates ) ) {
400
-				$plugins_need_update++;
401
-				$plugins_have_updates = true;
402
-			}
403
-		}
404
-
405
-		// Add a notice if there are outdated plugins.
406
-		if ( $plugins_need_update > 0 ) {
407
-			$result['status'] = 'critical';
408
-
409
-			$result['label'] = __( 'You have plugins waiting to be updated' );
410
-
411
-			$result['description'] .= sprintf(
412
-				'<p>%s</p>',
413
-				sprintf(
414
-					/* translators: %d: The number of outdated plugins. */
415
-					_n(
416
-						'Your site has %d plugin waiting to be updated.',
417
-						'Your site has %d plugins waiting to be updated.',
418
-						$plugins_need_update
419
-					),
420
-					$plugins_need_update
421
-				)
422
-			);
423
-
424
-			$result['actions'] .= sprintf(
425
-				'<p><a href="%s">%s</a></p>',
426
-				esc_url( network_admin_url( 'plugins.php?plugin_status=upgrade' ) ),
427
-				__( 'Update your plugins' )
428
-			);
429
-		} else {
430
-			if ( 1 === $plugins_active ) {
431
-				$result['description'] .= sprintf(
432
-					'<p>%s</p>',
433
-					__( 'Your site has 1 active plugin, and it is up to date.' )
434
-				);
435
-			} else {
436
-				$result['description'] .= sprintf(
437
-					'<p>%s</p>',
438
-					sprintf(
439
-						/* translators: %d: The number of active plugins. */
440
-						_n(
441
-							'Your site has %d active plugin, and it is up to date.',
442
-							'Your site has %d active plugins, and they are all up to date.',
443
-							$plugins_active
444
-						),
445
-						$plugins_active
446
-					)
447
-				);
448
-			}
449
-		}
450
-
451
-		// Check if there are inactive plugins.
452
-		if ( $plugins_total > $plugins_active && ! is_multisite() ) {
453
-			$unused_plugins = $plugins_total - $plugins_active;
454
-
455
-			$result['status'] = 'recommended';
456
-
457
-			$result['label'] = __( 'You should remove inactive plugins' );
458
-
459
-			$result['description'] .= sprintf(
460
-				'<p>%s %s</p>',
461
-				sprintf(
462
-					/* translators: %d: The number of inactive plugins. */
463
-					_n(
464
-						'Your site has %d inactive plugin.',
465
-						'Your site has %d inactive plugins.',
466
-						$unused_plugins
467
-					),
468
-					$unused_plugins
469
-				),
470
-				__( 'Inactive plugins are tempting targets for attackers. If you are not going to use a plugin, you should consider removing it.' )
471
-			);
472
-
473
-			$result['actions'] .= sprintf(
474
-				'<p><a href="%s">%s</a></p>',
475
-				esc_url( admin_url( 'plugins.php?plugin_status=inactive' ) ),
476
-				__( 'Manage inactive plugins' )
477
-			);
478
-		}
479
-
480
-		return $result;
481
-	}
482
-
483
-	/**
484
-	 * Test if themes are outdated, or unnecessary.
485
-	 *
486
-	 * Сhecks if your site has a default theme (to fall back on if there is a need),
487
-	 * if your themes are up to date and, finally, encourages you to remove any themes
488
-	 * that are not needed.
489
-	 *
490
-	 * @since 5.2.0
491
-	 *
492
-	 * @return array The test results.
493
-	 */
494
-	public function get_test_theme_version() {
495
-		$result = array(
496
-			'label'       => __( 'Your themes are all up to date' ),
497
-			'status'      => 'good',
498
-			'badge'       => array(
499
-				'label' => __( 'Security' ),
500
-				'color' => 'blue',
501
-			),
502
-			'description' => sprintf(
503
-				'<p>%s</p>',
504
-				__( 'Themes add your site&#8217;s look and feel. It&#8217;s important to keep them up to date, to stay consistent with your brand and keep your site secure.' )
505
-			),
506
-			'actions'     => sprintf(
507
-				'<p><a href="%s">%s</a></p>',
508
-				esc_url( admin_url( 'themes.php' ) ),
509
-				__( 'Manage your themes' )
510
-			),
511
-			'test'        => 'theme_version',
512
-		);
513
-
514
-		$theme_updates = get_theme_updates();
515
-
516
-		$themes_total        = 0;
517
-		$themes_need_updates = 0;
518
-		$themes_inactive     = 0;
519
-
520
-		// This value is changed during processing to determine how many themes are considered a reasonable amount.
521
-		$allowed_theme_count = 1;
522
-
523
-		$has_default_theme   = false;
524
-		$has_unused_themes   = false;
525
-		$show_unused_themes  = true;
526
-		$using_default_theme = false;
527
-
528
-		// Populate a list of all themes available in the install.
529
-		$all_themes   = wp_get_themes();
530
-		$active_theme = wp_get_theme();
531
-
532
-		// If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
533
-		$default_theme = wp_get_theme( WP_DEFAULT_THEME );
534
-		if ( ! $default_theme->exists() ) {
535
-			$default_theme = WP_Theme::get_core_default_theme();
536
-		}
537
-
538
-		if ( $default_theme ) {
539
-			$has_default_theme = true;
540
-
541
-			if (
542
-				$active_theme->get_stylesheet() === $default_theme->get_stylesheet()
543
-			||
544
-				is_child_theme() && $active_theme->get_template() === $default_theme->get_template()
545
-			) {
546
-				$using_default_theme = true;
547
-			}
548
-		}
549
-
550
-		foreach ( $all_themes as $theme_slug => $theme ) {
551
-			$themes_total++;
552
-
553
-			if ( array_key_exists( $theme_slug, $theme_updates ) ) {
554
-				$themes_need_updates++;
555
-			}
556
-		}
557
-
558
-		// If this is a child theme, increase the allowed theme count by one, to account for the parent.
559
-		if ( is_child_theme() ) {
560
-			$allowed_theme_count++;
561
-		}
562
-
563
-		// If there's a default theme installed and not in use, we count that as allowed as well.
564
-		if ( $has_default_theme && ! $using_default_theme ) {
565
-			$allowed_theme_count++;
566
-		}
567
-
568
-		if ( $themes_total > $allowed_theme_count ) {
569
-			$has_unused_themes = true;
570
-			$themes_inactive   = ( $themes_total - $allowed_theme_count );
571
-		}
572
-
573
-		// Check if any themes need to be updated.
574
-		if ( $themes_need_updates > 0 ) {
575
-			$result['status'] = 'critical';
576
-
577
-			$result['label'] = __( 'You have themes waiting to be updated' );
578
-
579
-			$result['description'] .= sprintf(
580
-				'<p>%s</p>',
581
-				sprintf(
582
-					/* translators: %d: The number of outdated themes. */
583
-					_n(
584
-						'Your site has %d theme waiting to be updated.',
585
-						'Your site has %d themes waiting to be updated.',
586
-						$themes_need_updates
587
-					),
588
-					$themes_need_updates
589
-				)
590
-			);
591
-		} else {
592
-			// Give positive feedback about the site being good about keeping things up to date.
593
-			if ( 1 === $themes_total ) {
594
-				$result['description'] .= sprintf(
595
-					'<p>%s</p>',
596
-					__( 'Your site has 1 installed theme, and it is up to date.' )
597
-				);
598
-			} else {
599
-				$result['description'] .= sprintf(
600
-					'<p>%s</p>',
601
-					sprintf(
602
-						/* translators: %d: The number of themes. */
603
-						_n(
604
-							'Your site has %d installed theme, and it is up to date.',
605
-							'Your site has %d installed themes, and they are all up to date.',
606
-							$themes_total
607
-						),
608
-						$themes_total
609
-					)
610
-				);
611
-			}
612
-		}
613
-
614
-		if ( $has_unused_themes && $show_unused_themes && ! is_multisite() ) {
615
-
616
-			// This is a child theme, so we want to be a bit more explicit in our messages.
617
-			if ( $active_theme->parent() ) {
618
-				// Recommend removing inactive themes, except a default theme, your current one, and the parent theme.
619
-				$result['status'] = 'recommended';
620
-
621
-				$result['label'] = __( 'You should remove inactive themes' );
622
-
623
-				if ( $using_default_theme ) {
624
-					$result['description'] .= sprintf(
625
-						'<p>%s %s</p>',
626
-						sprintf(
627
-							/* translators: %d: The number of inactive themes. */
628
-							_n(
629
-								'Your site has %d inactive theme.',
630
-								'Your site has %d inactive themes.',
631
-								$themes_inactive
632
-							),
633
-							$themes_inactive
634
-						),
635
-						sprintf(
636
-							/* translators: 1: The currently active theme. 2: The active theme's parent theme. */
637
-							__( 'To enhance your site&#8217;s security, you should consider removing any themes you are not using. You should keep your active theme, %1$s, and %2$s, its parent theme.' ),
638
-							$active_theme->name,
639
-							$active_theme->parent()->name
640
-						)
641
-					);
642
-				} else {
643
-					$result['description'] .= sprintf(
644
-						'<p>%s %s</p>',
645
-						sprintf(
646
-							/* translators: %d: The number of inactive themes. */
647
-							_n(
648
-								'Your site has %d inactive theme.',
649
-								'Your site has %d inactive themes.',
650
-								$themes_inactive
651
-							),
652
-							$themes_inactive
653
-						),
654
-						sprintf(
655
-							/* translators: 1: The default theme for WordPress. 2: The currently active theme. 3: The active theme's parent theme. */
656
-							__( 'To enhance your site&#8217;s security, you should consider removing any themes you are not using. You should keep %1$s, the default WordPress theme, %2$s, your active theme, and %3$s, its parent theme.' ),
657
-							$default_theme ? $default_theme->name : WP_DEFAULT_THEME,
658
-							$active_theme->name,
659
-							$active_theme->parent()->name
660
-						)
661
-					);
662
-				}
663
-			} else {
664
-				// Recommend removing all inactive themes.
665
-				$result['status'] = 'recommended';
666
-
667
-				$result['label'] = __( 'You should remove inactive themes' );
668
-
669
-				if ( $using_default_theme ) {
670
-					$result['description'] .= sprintf(
671
-						'<p>%s %s</p>',
672
-						sprintf(
673
-							/* translators: 1: The amount of inactive themes. 2: The currently active theme. */
674
-							_n(
675
-								'Your site has %1$d inactive theme, other than %2$s, your active theme.',
676
-								'Your site has %1$d inactive themes, other than %2$s, your active theme.',
677
-								$themes_inactive
678
-							),
679
-							$themes_inactive,
680
-							$active_theme->name
681
-						),
682
-						__( 'You should consider removing any unused themes to enhance your site&#8217;s security.' )
683
-					);
684
-				} else {
685
-					$result['description'] .= sprintf(
686
-						'<p>%s %s</p>',
687
-						sprintf(
688
-							/* translators: 1: The amount of inactive themes. 2: The default theme for WordPress. 3: The currently active theme. */
689
-							_n(
690
-								'Your site has %1$d inactive theme, other than %2$s, the default WordPress theme, and %3$s, your active theme.',
691
-								'Your site has %1$d inactive themes, other than %2$s, the default WordPress theme, and %3$s, your active theme.',
692
-								$themes_inactive
693
-							),
694
-							$themes_inactive,
695
-							$default_theme ? $default_theme->name : WP_DEFAULT_THEME,
696
-							$active_theme->name
697
-						),
698
-						__( 'You should consider removing any unused themes to enhance your site&#8217;s security.' )
699
-					);
700
-				}
701
-			}
702
-		}
703
-
704
-		// If no default Twenty* theme exists.
705
-		if ( ! $has_default_theme ) {
706
-			$result['status'] = 'recommended';
707
-
708
-			$result['label'] = __( 'Have a default theme available' );
709
-
710
-			$result['description'] .= sprintf(
711
-				'<p>%s</p>',
712
-				__( 'Your site does not have any default theme. Default themes are used by WordPress automatically if anything is wrong with your chosen theme.' )
713
-			);
714
-		}
715
-
716
-		return $result;
717
-	}
718
-
719
-	/**
720
-	 * Test if the supplied PHP version is supported.
721
-	 *
722
-	 * @since 5.2.0
723
-	 *
724
-	 * @return array The test results.
725
-	 */
726
-	public function get_test_php_version() {
727
-		$response = wp_check_php_version();
728
-
729
-		$result = array(
730
-			'label'       => sprintf(
731
-				/* translators: %s: The current PHP version. */
732
-				__( 'Your site is running the current version of PHP (%s)' ),
733
-				PHP_VERSION
734
-			),
735
-			'status'      => 'good',
736
-			'badge'       => array(
737
-				'label' => __( 'Performance' ),
738
-				'color' => 'blue',
739
-			),
740
-			'description' => sprintf(
741
-				'<p>%s</p>',
742
-				sprintf(
743
-					/* translators: %s: The minimum recommended PHP version. */
744
-					__( 'PHP is the programming language used to build and maintain WordPress. Newer versions of PHP are created with increased performance in mind, so you may see a positive effect on your site&#8217;s performance. The minimum recommended version of PHP is %s.' ),
745
-					$response ? $response['recommended_version'] : ''
746
-				)
747
-			),
748
-			'actions'     => sprintf(
749
-				'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
750
-				esc_url( wp_get_update_php_url() ),
751
-				__( 'Learn more about updating PHP' ),
752
-				/* translators: Accessibility text. */
753
-				__( '(opens in a new tab)' )
754
-			),
755
-			'test'        => 'php_version',
756
-		);
757
-
758
-		// PHP is up to date.
759
-		if ( ! $response || version_compare( PHP_VERSION, $response['recommended_version'], '>=' ) ) {
760
-			return $result;
761
-		}
762
-
763
-		// The PHP version is older than the recommended version, but still receiving active support.
764
-		if ( $response['is_supported'] ) {
765
-			$result['label'] = sprintf(
766
-				/* translators: %s: The server PHP version. */
767
-				__( 'Your site is running an older version of PHP (%s)' ),
768
-				PHP_VERSION
769
-			);
770
-			$result['status'] = 'recommended';
771
-
772
-			return $result;
773
-		}
774
-
775
-		// The PHP version is only receiving security fixes.
776
-		if ( $response['is_secure'] ) {
777
-			$result['label'] = sprintf(
778
-				/* translators: %s: The server PHP version. */
779
-				__( 'Your site is running an older version of PHP (%s), which should be updated' ),
780
-				PHP_VERSION
781
-			);
782
-			$result['status'] = 'recommended';
783
-
784
-			return $result;
785
-		}
786
-
787
-		// Anything no longer secure must be updated.
788
-		$result['label'] = sprintf(
789
-			/* translators: %s: The server PHP version. */
790
-			__( 'Your site is running an outdated version of PHP (%s), which requires an update' ),
791
-			PHP_VERSION
792
-		);
793
-		$result['status']         = 'critical';
794
-		$result['badge']['label'] = __( 'Security' );
795
-
796
-		return $result;
797
-	}
798
-
799
-	/**
800
-	 * Check if the passed extension or function are available.
801
-	 *
802
-	 * Make the check for available PHP modules into a simple boolean operator for a cleaner test runner.
803
-	 *
804
-	 * @since 5.2.0
805
-	 * @since 5.3.0 The `$constant_name` and `$class_name` parameters were added.
806
-	 *
807
-	 * @param string $extension_name Optional. The extension name to test. Default null.
808
-	 * @param string $function_name  Optional. The function name to test. Default null.
809
-	 * @param string $constant_name  Optional. The constant name to test for. Default null.
810
-	 * @param string $class_name     Optional. The class name to test for. Default null.
811
-	 * @return bool Whether or not the extension and function are available.
812
-	 */
813
-	private function test_php_extension_availability( $extension_name = null, $function_name = null, $constant_name = null, $class_name = null ) {
814
-		// If no extension or function is passed, claim to fail testing, as we have nothing to test against.
815
-		if ( ! $extension_name && ! $function_name && ! $constant_name && ! $class_name ) {
816
-			return false;
817
-		}
818
-
819
-		if ( $extension_name && ! extension_loaded( $extension_name ) ) {
820
-			return false;
821
-		}
822
-
823
-		if ( $function_name && ! function_exists( $function_name ) ) {
824
-			return false;
825
-		}
826
-
827
-		if ( $constant_name && ! defined( $constant_name ) ) {
828
-			return false;
829
-		}
830
-
831
-		if ( $class_name && ! class_exists( $class_name ) ) {
832
-			return false;
833
-		}
834
-
835
-		return true;
836
-	}
837
-
838
-	/**
839
-	 * Test if required PHP modules are installed on the host.
840
-	 *
841
-	 * This test builds on the recommendations made by the WordPress Hosting Team
842
-	 * as seen at https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions
843
-	 *
844
-	 * @since 5.2.0
845
-	 *
846
-	 * @return array
847
-	 */
848
-	public function get_test_php_extensions() {
849
-		$result = array(
850
-			'label'       => __( 'Required and recommended modules are installed' ),
851
-			'status'      => 'good',
852
-			'badge'       => array(
853
-				'label' => __( 'Performance' ),
854
-				'color' => 'blue',
855
-			),
856
-			'description' => sprintf(
857
-				'<p>%s</p><p>%s</p>',
858
-				__( 'PHP modules perform most of the tasks on the server that make your site run. Any changes to these must be made by your server administrator.' ),
859
-				sprintf(
860
-					/* translators: 1: Link to the hosting group page about recommended PHP modules. 2: Additional link attributes. 3: Accessibility text. */
861
-					__( 'The WordPress Hosting Team maintains a list of those modules, both recommended and required, in <a href="%1$s" %2$s>the team handbook%3$s</a>.' ),
862
-					/* translators: Localized team handbook, if one exists. */
863
-					esc_url( __( 'https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions' ) ),
864
-					'target="_blank" rel="noopener"',
865
-					sprintf(
866
-						' <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span>',
867
-						/* translators: Accessibility text. */
868
-						__( '(opens in a new tab)' )
869
-					)
870
-				)
871
-			),
872
-			'actions'     => '',
873
-			'test'        => 'php_extensions',
874
-		);
875
-
876
-		$modules = array(
877
-			'curl'      => array(
878
-				'function' => 'curl_version',
879
-				'required' => false,
880
-			),
881
-			'dom'       => array(
882
-				'class'    => 'DOMNode',
883
-				'required' => false,
884
-			),
885
-			'exif'      => array(
886
-				'function' => 'exif_read_data',
887
-				'required' => false,
888
-			),
889
-			'fileinfo'  => array(
890
-				'function' => 'finfo_file',
891
-				'required' => false,
892
-			),
893
-			'hash'      => array(
894
-				'function' => 'hash',
895
-				'required' => false,
896
-			),
897
-			'imagick'   => array(
898
-				'extension' => 'imagick',
899
-				'required'  => false,
900
-			),
901
-			'json'      => array(
902
-				'function' => 'json_last_error',
903
-				'required' => true,
904
-			),
905
-			'mbstring'  => array(
906
-				'function' => 'mb_check_encoding',
907
-				'required' => false,
908
-			),
909
-			'mysqli'    => array(
910
-				'function' => 'mysqli_connect',
911
-				'required' => false,
912
-			),
913
-			'libsodium' => array(
914
-				'constant'            => 'SODIUM_LIBRARY_VERSION',
915
-				'required'            => false,
916
-				'php_bundled_version' => '7.2.0',
917
-			),
918
-			'openssl'   => array(
919
-				'function' => 'openssl_encrypt',
920
-				'required' => false,
921
-			),
922
-			'pcre'      => array(
923
-				'function' => 'preg_match',
924
-				'required' => false,
925
-			),
926
-			'mod_xml'   => array(
927
-				'extension' => 'libxml',
928
-				'required'  => false,
929
-			),
930
-			'zip'       => array(
931
-				'class'    => 'ZipArchive',
932
-				'required' => false,
933
-			),
934
-			'filter'    => array(
935
-				'function' => 'filter_list',
936
-				'required' => false,
937
-			),
938
-			'gd'        => array(
939
-				'extension'    => 'gd',
940
-				'required'     => false,
941
-				'fallback_for' => 'imagick',
942
-			),
943
-			'iconv'     => array(
944
-				'function' => 'iconv',
945
-				'required' => false,
946
-			),
947
-			'intl'      => array(
948
-				'extension' => 'intl',
949
-				'required'  => false,
950
-			),
951
-			'mcrypt'    => array(
952
-				'extension'    => 'mcrypt',
953
-				'required'     => false,
954
-				'fallback_for' => 'libsodium',
955
-			),
956
-			'simplexml' => array(
957
-				'extension'    => 'simplexml',
958
-				'required'     => false,
959
-				'fallback_for' => 'mod_xml',
960
-			),
961
-			'xmlreader' => array(
962
-				'extension'    => 'xmlreader',
963
-				'required'     => false,
964
-				'fallback_for' => 'mod_xml',
965
-			),
966
-			'zlib'      => array(
967
-				'extension'    => 'zlib',
968
-				'required'     => false,
969
-				'fallback_for' => 'zip',
970
-			),
971
-		);
972
-
973
-		/**
974
-		 * An array representing all the modules we wish to test for.
975
-		 *
976
-		 * @since 5.2.0
977
-		 * @since 5.3.0 The `$constant` and `$class` parameters were added.
978
-		 *
979
-		 * @param array $modules {
980
-		 *     An associative array of modules to test for.
981
-		 *
982
-		 *     @type array ...$0 {
983
-		 *         An associative array of module properties used during testing.
984
-		 *         One of either `$function` or `$extension` must be provided, or they will fail by default.
985
-		 *
986
-		 *         @type string $function     Optional. A function name to test for the existence of.
987
-		 *         @type string $extension    Optional. An extension to check if is loaded in PHP.
988
-		 *         @type string $constant     Optional. A constant name to check for to verify an extension exists.
989
-		 *         @type string $class        Optional. A class name to check for to verify an extension exists.
990
-		 *         @type bool   $required     Is this a required feature or not.
991
-		 *         @type string $fallback_for Optional. The module this module replaces as a fallback.
992
-		 *     }
993
-		 * }
994
-		 */
995
-		$modules = apply_filters( 'site_status_test_php_modules', $modules );
996
-
997
-		$failures = array();
998
-
999
-		foreach ( $modules as $library => $module ) {
1000
-			$extension_name = ( isset( $module['extension'] ) ? $module['extension'] : null );
1001
-			$function_name  = ( isset( $module['function'] ) ? $module['function'] : null );
1002
-			$constant_name  = ( isset( $module['constant'] ) ? $module['constant'] : null );
1003
-			$class_name     = ( isset( $module['class'] ) ? $module['class'] : null );
1004
-
1005
-			// If this module is a fallback for another function, check if that other function passed.
1006
-			if ( isset( $module['fallback_for'] ) ) {
1007
-				/*
11
+    private static $instance = null;
12
+
13
+    private $mysql_min_version_check;
14
+    private $mysql_rec_version_check;
15
+
16
+    public $is_mariadb                           = false;
17
+    private $mysql_server_version                = '';
18
+    private $health_check_mysql_required_version = '5.5';
19
+    private $health_check_mysql_rec_version      = '';
20
+
21
+    public $php_memory_limit;
22
+
23
+    public $schedules;
24
+    public $crons;
25
+    public $last_missed_cron     = null;
26
+    public $last_late_cron       = null;
27
+    private $timeout_missed_cron = null;
28
+    private $timeout_late_cron   = null;
29
+
30
+    /**
31
+     * WP_Site_Health constructor.
32
+     *
33
+     * @since 5.2.0
34
+     */
35
+    public function __construct() {
36
+        $this->maybe_create_scheduled_event();
37
+
38
+        // Save memory limit before it's affected by wp_raise_memory_limit( 'admin' ).
39
+        $this->php_memory_limit = ini_get( 'memory_limit' );
40
+
41
+        $this->timeout_late_cron   = 0;
42
+        $this->timeout_missed_cron = - 5 * MINUTE_IN_SECONDS;
43
+
44
+        if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
45
+            $this->timeout_late_cron   = - 15 * MINUTE_IN_SECONDS;
46
+            $this->timeout_missed_cron = - 1 * HOUR_IN_SECONDS;
47
+        }
48
+
49
+        add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
50
+
51
+        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
52
+        add_action( 'wp_site_health_scheduled_check', array( $this, 'wp_cron_scheduled_check' ) );
53
+
54
+        add_action( 'site_health_tab_content', array( $this, 'show_site_health_tab' ) );
55
+    }
56
+
57
+    /**
58
+     * Output the content of a tab in the Site Health screen.
59
+     *
60
+     * @since 5.8.0
61
+     *
62
+     * @param string $tab Slug of the current tab being displayed.
63
+     */
64
+    public function show_site_health_tab( $tab ) {
65
+        if ( 'debug' === $tab ) {
66
+            require_once ABSPATH . '/wp-admin/site-health-info.php';
67
+        }
68
+    }
69
+
70
+    /**
71
+     * Return an instance of the WP_Site_Health class, or create one if none exist yet.
72
+     *
73
+     * @since 5.4.0
74
+     *
75
+     * @return WP_Site_Health|null
76
+     */
77
+    public static function get_instance() {
78
+        if ( null === self::$instance ) {
79
+            self::$instance = new WP_Site_Health();
80
+        }
81
+
82
+        return self::$instance;
83
+    }
84
+
85
+    /**
86
+     * Enqueues the site health scripts.
87
+     *
88
+     * @since 5.2.0
89
+     */
90
+    public function enqueue_scripts() {
91
+        $screen = get_current_screen();
92
+        if ( 'site-health' !== $screen->id && 'dashboard' !== $screen->id ) {
93
+            return;
94
+        }
95
+
96
+        $health_check_js_variables = array(
97
+            'screen'      => $screen->id,
98
+            'nonce'       => array(
99
+                'site_status'        => wp_create_nonce( 'health-check-site-status' ),
100
+                'site_status_result' => wp_create_nonce( 'health-check-site-status-result' ),
101
+            ),
102
+            'site_status' => array(
103
+                'direct' => array(),
104
+                'async'  => array(),
105
+                'issues' => array(
106
+                    'good'        => 0,
107
+                    'recommended' => 0,
108
+                    'critical'    => 0,
109
+                ),
110
+            ),
111
+        );
112
+
113
+        $issue_counts = get_transient( 'health-check-site-status-result' );
114
+
115
+        if ( false !== $issue_counts ) {
116
+            $issue_counts = json_decode( $issue_counts );
117
+
118
+            $health_check_js_variables['site_status']['issues'] = $issue_counts;
119
+        }
120
+
121
+        if ( 'site-health' === $screen->id && ( ! isset( $_GET['tab'] ) || empty( $_GET['tab'] ) ) ) {
122
+            $tests = WP_Site_Health::get_tests();
123
+
124
+            // Don't run https test on development environments.
125
+            if ( $this->is_development_environment() ) {
126
+                unset( $tests['async']['https_status'] );
127
+            }
128
+
129
+            foreach ( $tests['direct'] as $test ) {
130
+                if ( is_string( $test['test'] ) ) {
131
+                    $test_function = sprintf(
132
+                        'get_test_%s',
133
+                        $test['test']
134
+                    );
135
+
136
+                    if ( method_exists( $this, $test_function ) && is_callable( array( $this, $test_function ) ) ) {
137
+                        $health_check_js_variables['site_status']['direct'][] = $this->perform_test( array( $this, $test_function ) );
138
+                        continue;
139
+                    }
140
+                }
141
+
142
+                if ( is_callable( $test['test'] ) ) {
143
+                    $health_check_js_variables['site_status']['direct'][] = $this->perform_test( $test['test'] );
144
+                }
145
+            }
146
+
147
+            foreach ( $tests['async'] as $test ) {
148
+                if ( is_string( $test['test'] ) ) {
149
+                    $health_check_js_variables['site_status']['async'][] = array(
150
+                        'test'      => $test['test'],
151
+                        'has_rest'  => ( isset( $test['has_rest'] ) ? $test['has_rest'] : false ),
152
+                        'completed' => false,
153
+                        'headers'   => isset( $test['headers'] ) ? $test['headers'] : array(),
154
+                    );
155
+                }
156
+            }
157
+        }
158
+
159
+        wp_localize_script( 'site-health', 'SiteHealth', $health_check_js_variables );
160
+    }
161
+
162
+    /**
163
+     * Run a Site Health test directly.
164
+     *
165
+     * @since 5.4.0
166
+     *
167
+     * @param callable $callback
168
+     * @return mixed|void
169
+     */
170
+    private function perform_test( $callback ) {
171
+        /**
172
+         * Filters the output of a finished Site Health test.
173
+         *
174
+         * @since 5.3.0
175
+         *
176
+         * @param array $test_result {
177
+         *     An associative array of test result data.
178
+         *
179
+         *     @type string $label       A label describing the test, and is used as a header in the output.
180
+         *     @type string $status      The status of the test, which can be a value of `good`, `recommended` or `critical`.
181
+         *     @type array  $badge {
182
+         *         Tests are put into categories which have an associated badge shown, these can be modified and assigned here.
183
+         *
184
+         *         @type string $label The test label, for example `Performance`.
185
+         *         @type string $color Default `blue`. A string representing a color to use for the label.
186
+         *     }
187
+         *     @type string $description A more descriptive explanation of what the test looks for, and why it is important for the end user.
188
+         *     @type string $actions     An action to direct the user to where they can resolve the issue, if one exists.
189
+         *     @type string $test        The name of the test being ran, used as a reference point.
190
+         * }
191
+         */
192
+        return apply_filters( 'site_status_test_result', call_user_func( $callback ) );
193
+    }
194
+
195
+    /**
196
+     * Run the SQL version checks.
197
+     *
198
+     * These values are used in later tests, but the part of preparing them is more easily managed
199
+     * early in the class for ease of access and discovery.
200
+     *
201
+     * @since 5.2.0
202
+     *
203
+     * @global wpdb $wpdb WordPress database abstraction object.
204
+     */
205
+    private function prepare_sql_data() {
206
+        global $wpdb;
207
+
208
+        if ( $wpdb->use_mysqli ) {
209
+            // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
210
+            $mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
211
+        } else {
212
+            // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
213
+            $mysql_server_type = mysql_get_server_info( $wpdb->dbh );
214
+        }
215
+
216
+        $this->mysql_server_version = $wpdb->get_var( 'SELECT VERSION()' );
217
+
218
+        $this->health_check_mysql_rec_version = '5.6';
219
+
220
+        if ( stristr( $mysql_server_type, 'mariadb' ) ) {
221
+            $this->is_mariadb                     = true;
222
+            $this->health_check_mysql_rec_version = '10.0';
223
+        }
224
+
225
+        $this->mysql_min_version_check = version_compare( '5.5', $this->mysql_server_version, '<=' );
226
+        $this->mysql_rec_version_check = version_compare( $this->health_check_mysql_rec_version, $this->mysql_server_version, '<=' );
227
+    }
228
+
229
+    /**
230
+     * Test if `wp_version_check` is blocked.
231
+     *
232
+     * It's possible to block updates with the `wp_version_check` filter, but this can't be checked
233
+     * during an Ajax call, as the filter is never introduced then.
234
+     *
235
+     * This filter overrides a standard page request if it's made by an admin through the Ajax call
236
+     * with the right query argument to check for this.
237
+     *
238
+     * @since 5.2.0
239
+     */
240
+    public function check_wp_version_check_exists() {
241
+        if ( ! is_admin() || ! is_user_logged_in() || ! current_user_can( 'update_core' ) || ! isset( $_GET['health-check-test-wp_version_check'] ) ) {
242
+            return;
243
+        }
244
+
245
+        echo ( has_filter( 'wp_version_check', 'wp_version_check' ) ? 'yes' : 'no' );
246
+
247
+        die();
248
+    }
249
+
250
+    /**
251
+     * Tests for WordPress version and outputs it.
252
+     *
253
+     * Gives various results depending on what kind of updates are available, if any, to encourage
254
+     * the user to install security updates as a priority.
255
+     *
256
+     * @since 5.2.0
257
+     *
258
+     * @return array The test result.
259
+     */
260
+    public function get_test_wordpress_version() {
261
+        $result = array(
262
+            'label'       => '',
263
+            'status'      => '',
264
+            'badge'       => array(
265
+                'label' => __( 'Performance' ),
266
+                'color' => 'blue',
267
+            ),
268
+            'description' => '',
269
+            'actions'     => '',
270
+            'test'        => 'wordpress_version',
271
+        );
272
+
273
+        $core_current_version = get_bloginfo( 'version' );
274
+        $core_updates         = get_core_updates();
275
+
276
+        if ( ! is_array( $core_updates ) ) {
277
+            $result['status'] = 'recommended';
278
+
279
+            $result['label'] = sprintf(
280
+                /* translators: %s: Your current version of WordPress. */
281
+                __( 'WordPress version %s' ),
282
+                $core_current_version
283
+            );
284
+
285
+            $result['description'] = sprintf(
286
+                '<p>%s</p>',
287
+                __( 'Unable to check if any new versions of WordPress are available.' )
288
+            );
289
+
290
+            $result['actions'] = sprintf(
291
+                '<a href="%s">%s</a>',
292
+                esc_url( admin_url( 'update-core.php?force-check=1' ) ),
293
+                __( 'Check for updates manually' )
294
+            );
295
+        } else {
296
+            foreach ( $core_updates as $core => $update ) {
297
+                if ( 'upgrade' === $update->response ) {
298
+                    $current_version = explode( '.', $core_current_version );
299
+                    $new_version     = explode( '.', $update->version );
300
+
301
+                    $current_major = $current_version[0] . '.' . $current_version[1];
302
+                    $new_major     = $new_version[0] . '.' . $new_version[1];
303
+
304
+                    $result['label'] = sprintf(
305
+                        /* translators: %s: The latest version of WordPress available. */
306
+                        __( 'WordPress update available (%s)' ),
307
+                        $update->version
308
+                    );
309
+
310
+                    $result['actions'] = sprintf(
311
+                        '<a href="%s">%s</a>',
312
+                        esc_url( admin_url( 'update-core.php' ) ),
313
+                        __( 'Install the latest version of WordPress' )
314
+                    );
315
+
316
+                    if ( $current_major !== $new_major ) {
317
+                        // This is a major version mismatch.
318
+                        $result['status']      = 'recommended';
319
+                        $result['description'] = sprintf(
320
+                            '<p>%s</p>',
321
+                            __( 'A new version of WordPress is available.' )
322
+                        );
323
+                    } else {
324
+                        // This is a minor version, sometimes considered more critical.
325
+                        $result['status']         = 'critical';
326
+                        $result['badge']['label'] = __( 'Security' );
327
+                        $result['description']    = sprintf(
328
+                            '<p>%s</p>',
329
+                            __( 'A new minor update is available for your site. Because minor updates often address security, it&#8217;s important to install them.' )
330
+                        );
331
+                    }
332
+                } else {
333
+                    $result['status'] = 'good';
334
+                    $result['label']  = sprintf(
335
+                        /* translators: %s: The current version of WordPress installed on this site. */
336
+                        __( 'Your version of WordPress (%s) is up to date' ),
337
+                        $core_current_version
338
+                    );
339
+
340
+                    $result['description'] = sprintf(
341
+                        '<p>%s</p>',
342
+                        __( 'You are currently running the latest version of WordPress available, keep it up!' )
343
+                    );
344
+                }
345
+            }
346
+        }
347
+
348
+        return $result;
349
+    }
350
+
351
+    /**
352
+     * Test if plugins are outdated, or unnecessary.
353
+     *
354
+     * The tests checks if your plugins are up to date, and encourages you to remove any
355
+     * that are not in use.
356
+     *
357
+     * @since 5.2.0
358
+     *
359
+     * @return array The test result.
360
+     */
361
+    public function get_test_plugin_version() {
362
+        $result = array(
363
+            'label'       => __( 'Your plugins are all up to date' ),
364
+            'status'      => 'good',
365
+            'badge'       => array(
366
+                'label' => __( 'Security' ),
367
+                'color' => 'blue',
368
+            ),
369
+            'description' => sprintf(
370
+                '<p>%s</p>',
371
+                __( 'Plugins extend your site&#8217;s functionality with things like contact forms, ecommerce and much more. That means they have deep access to your site, so it&#8217;s vital to keep them up to date.' )
372
+            ),
373
+            'actions'     => sprintf(
374
+                '<p><a href="%s">%s</a></p>',
375
+                esc_url( admin_url( 'plugins.php' ) ),
376
+                __( 'Manage your plugins' )
377
+            ),
378
+            'test'        => 'plugin_version',
379
+        );
380
+
381
+        $plugins        = get_plugins();
382
+        $plugin_updates = get_plugin_updates();
383
+
384
+        $plugins_have_updates = false;
385
+        $plugins_active       = 0;
386
+        $plugins_total        = 0;
387
+        $plugins_need_update  = 0;
388
+
389
+        // Loop over the available plugins and check their versions and active state.
390
+        foreach ( $plugins as $plugin_path => $plugin ) {
391
+            $plugins_total++;
392
+
393
+            if ( is_plugin_active( $plugin_path ) ) {
394
+                $plugins_active++;
395
+            }
396
+
397
+            $plugin_version = $plugin['Version'];
398
+
399
+            if ( array_key_exists( $plugin_path, $plugin_updates ) ) {
400
+                $plugins_need_update++;
401
+                $plugins_have_updates = true;
402
+            }
403
+        }
404
+
405
+        // Add a notice if there are outdated plugins.
406
+        if ( $plugins_need_update > 0 ) {
407
+            $result['status'] = 'critical';
408
+
409
+            $result['label'] = __( 'You have plugins waiting to be updated' );
410
+
411
+            $result['description'] .= sprintf(
412
+                '<p>%s</p>',
413
+                sprintf(
414
+                    /* translators: %d: The number of outdated plugins. */
415
+                    _n(
416
+                        'Your site has %d plugin waiting to be updated.',
417
+                        'Your site has %d plugins waiting to be updated.',
418
+                        $plugins_need_update
419
+                    ),
420
+                    $plugins_need_update
421
+                )
422
+            );
423
+
424
+            $result['actions'] .= sprintf(
425
+                '<p><a href="%s">%s</a></p>',
426
+                esc_url( network_admin_url( 'plugins.php?plugin_status=upgrade' ) ),
427
+                __( 'Update your plugins' )
428
+            );
429
+        } else {
430
+            if ( 1 === $plugins_active ) {
431
+                $result['description'] .= sprintf(
432
+                    '<p>%s</p>',
433
+                    __( 'Your site has 1 active plugin, and it is up to date.' )
434
+                );
435
+            } else {
436
+                $result['description'] .= sprintf(
437
+                    '<p>%s</p>',
438
+                    sprintf(
439
+                        /* translators: %d: The number of active plugins. */
440
+                        _n(
441
+                            'Your site has %d active plugin, and it is up to date.',
442
+                            'Your site has %d active plugins, and they are all up to date.',
443
+                            $plugins_active
444
+                        ),
445
+                        $plugins_active
446
+                    )
447
+                );
448
+            }
449
+        }
450
+
451
+        // Check if there are inactive plugins.
452
+        if ( $plugins_total > $plugins_active && ! is_multisite() ) {
453
+            $unused_plugins = $plugins_total - $plugins_active;
454
+
455
+            $result['status'] = 'recommended';
456
+
457
+            $result['label'] = __( 'You should remove inactive plugins' );
458
+
459
+            $result['description'] .= sprintf(
460
+                '<p>%s %s</p>',
461
+                sprintf(
462
+                    /* translators: %d: The number of inactive plugins. */
463
+                    _n(
464
+                        'Your site has %d inactive plugin.',
465
+                        'Your site has %d inactive plugins.',
466
+                        $unused_plugins
467
+                    ),
468
+                    $unused_plugins
469
+                ),
470
+                __( 'Inactive plugins are tempting targets for attackers. If you are not going to use a plugin, you should consider removing it.' )
471
+            );
472
+
473
+            $result['actions'] .= sprintf(
474
+                '<p><a href="%s">%s</a></p>',
475
+                esc_url( admin_url( 'plugins.php?plugin_status=inactive' ) ),
476
+                __( 'Manage inactive plugins' )
477
+            );
478
+        }
479
+
480
+        return $result;
481
+    }
482
+
483
+    /**
484
+     * Test if themes are outdated, or unnecessary.
485
+     *
486
+     * Сhecks if your site has a default theme (to fall back on if there is a need),
487
+     * if your themes are up to date and, finally, encourages you to remove any themes
488
+     * that are not needed.
489
+     *
490
+     * @since 5.2.0
491
+     *
492
+     * @return array The test results.
493
+     */
494
+    public function get_test_theme_version() {
495
+        $result = array(
496
+            'label'       => __( 'Your themes are all up to date' ),
497
+            'status'      => 'good',
498
+            'badge'       => array(
499
+                'label' => __( 'Security' ),
500
+                'color' => 'blue',
501
+            ),
502
+            'description' => sprintf(
503
+                '<p>%s</p>',
504
+                __( 'Themes add your site&#8217;s look and feel. It&#8217;s important to keep them up to date, to stay consistent with your brand and keep your site secure.' )
505
+            ),
506
+            'actions'     => sprintf(
507
+                '<p><a href="%s">%s</a></p>',
508
+                esc_url( admin_url( 'themes.php' ) ),
509
+                __( 'Manage your themes' )
510
+            ),
511
+            'test'        => 'theme_version',
512
+        );
513
+
514
+        $theme_updates = get_theme_updates();
515
+
516
+        $themes_total        = 0;
517
+        $themes_need_updates = 0;
518
+        $themes_inactive     = 0;
519
+
520
+        // This value is changed during processing to determine how many themes are considered a reasonable amount.
521
+        $allowed_theme_count = 1;
522
+
523
+        $has_default_theme   = false;
524
+        $has_unused_themes   = false;
525
+        $show_unused_themes  = true;
526
+        $using_default_theme = false;
527
+
528
+        // Populate a list of all themes available in the install.
529
+        $all_themes   = wp_get_themes();
530
+        $active_theme = wp_get_theme();
531
+
532
+        // If WP_DEFAULT_THEME doesn't exist, fall back to the latest core default theme.
533
+        $default_theme = wp_get_theme( WP_DEFAULT_THEME );
534
+        if ( ! $default_theme->exists() ) {
535
+            $default_theme = WP_Theme::get_core_default_theme();
536
+        }
537
+
538
+        if ( $default_theme ) {
539
+            $has_default_theme = true;
540
+
541
+            if (
542
+                $active_theme->get_stylesheet() === $default_theme->get_stylesheet()
543
+            ||
544
+                is_child_theme() && $active_theme->get_template() === $default_theme->get_template()
545
+            ) {
546
+                $using_default_theme = true;
547
+            }
548
+        }
549
+
550
+        foreach ( $all_themes as $theme_slug => $theme ) {
551
+            $themes_total++;
552
+
553
+            if ( array_key_exists( $theme_slug, $theme_updates ) ) {
554
+                $themes_need_updates++;
555
+            }
556
+        }
557
+
558
+        // If this is a child theme, increase the allowed theme count by one, to account for the parent.
559
+        if ( is_child_theme() ) {
560
+            $allowed_theme_count++;
561
+        }
562
+
563
+        // If there's a default theme installed and not in use, we count that as allowed as well.
564
+        if ( $has_default_theme && ! $using_default_theme ) {
565
+            $allowed_theme_count++;
566
+        }
567
+
568
+        if ( $themes_total > $allowed_theme_count ) {
569
+            $has_unused_themes = true;
570
+            $themes_inactive   = ( $themes_total - $allowed_theme_count );
571
+        }
572
+
573
+        // Check if any themes need to be updated.
574
+        if ( $themes_need_updates > 0 ) {
575
+            $result['status'] = 'critical';
576
+
577
+            $result['label'] = __( 'You have themes waiting to be updated' );
578
+
579
+            $result['description'] .= sprintf(
580
+                '<p>%s</p>',
581
+                sprintf(
582
+                    /* translators: %d: The number of outdated themes. */
583
+                    _n(
584
+                        'Your site has %d theme waiting to be updated.',
585
+                        'Your site has %d themes waiting to be updated.',
586
+                        $themes_need_updates
587
+                    ),
588
+                    $themes_need_updates
589
+                )
590
+            );
591
+        } else {
592
+            // Give positive feedback about the site being good about keeping things up to date.
593
+            if ( 1 === $themes_total ) {
594
+                $result['description'] .= sprintf(
595
+                    '<p>%s</p>',
596
+                    __( 'Your site has 1 installed theme, and it is up to date.' )
597
+                );
598
+            } else {
599
+                $result['description'] .= sprintf(
600
+                    '<p>%s</p>',
601
+                    sprintf(
602
+                        /* translators: %d: The number of themes. */
603
+                        _n(
604
+                            'Your site has %d installed theme, and it is up to date.',
605
+                            'Your site has %d installed themes, and they are all up to date.',
606
+                            $themes_total
607
+                        ),
608
+                        $themes_total
609
+                    )
610
+                );
611
+            }
612
+        }
613
+
614
+        if ( $has_unused_themes && $show_unused_themes && ! is_multisite() ) {
615
+
616
+            // This is a child theme, so we want to be a bit more explicit in our messages.
617
+            if ( $active_theme->parent() ) {
618
+                // Recommend removing inactive themes, except a default theme, your current one, and the parent theme.
619
+                $result['status'] = 'recommended';
620
+
621
+                $result['label'] = __( 'You should remove inactive themes' );
622
+
623
+                if ( $using_default_theme ) {
624
+                    $result['description'] .= sprintf(
625
+                        '<p>%s %s</p>',
626
+                        sprintf(
627
+                            /* translators: %d: The number of inactive themes. */
628
+                            _n(
629
+                                'Your site has %d inactive theme.',
630
+                                'Your site has %d inactive themes.',
631
+                                $themes_inactive
632
+                            ),
633
+                            $themes_inactive
634
+                        ),
635
+                        sprintf(
636
+                            /* translators: 1: The currently active theme. 2: The active theme's parent theme. */
637
+                            __( 'To enhance your site&#8217;s security, you should consider removing any themes you are not using. You should keep your active theme, %1$s, and %2$s, its parent theme.' ),
638
+                            $active_theme->name,
639
+                            $active_theme->parent()->name
640
+                        )
641
+                    );
642
+                } else {
643
+                    $result['description'] .= sprintf(
644
+                        '<p>%s %s</p>',
645
+                        sprintf(
646
+                            /* translators: %d: The number of inactive themes. */
647
+                            _n(
648
+                                'Your site has %d inactive theme.',
649
+                                'Your site has %d inactive themes.',
650
+                                $themes_inactive
651
+                            ),
652
+                            $themes_inactive
653
+                        ),
654
+                        sprintf(
655
+                            /* translators: 1: The default theme for WordPress. 2: The currently active theme. 3: The active theme's parent theme. */
656
+                            __( 'To enhance your site&#8217;s security, you should consider removing any themes you are not using. You should keep %1$s, the default WordPress theme, %2$s, your active theme, and %3$s, its parent theme.' ),
657
+                            $default_theme ? $default_theme->name : WP_DEFAULT_THEME,
658
+                            $active_theme->name,
659
+                            $active_theme->parent()->name
660
+                        )
661
+                    );
662
+                }
663
+            } else {
664
+                // Recommend removing all inactive themes.
665
+                $result['status'] = 'recommended';
666
+
667
+                $result['label'] = __( 'You should remove inactive themes' );
668
+
669
+                if ( $using_default_theme ) {
670
+                    $result['description'] .= sprintf(
671
+                        '<p>%s %s</p>',
672
+                        sprintf(
673
+                            /* translators: 1: The amount of inactive themes. 2: The currently active theme. */
674
+                            _n(
675
+                                'Your site has %1$d inactive theme, other than %2$s, your active theme.',
676
+                                'Your site has %1$d inactive themes, other than %2$s, your active theme.',
677
+                                $themes_inactive
678
+                            ),
679
+                            $themes_inactive,
680
+                            $active_theme->name
681
+                        ),
682
+                        __( 'You should consider removing any unused themes to enhance your site&#8217;s security.' )
683
+                    );
684
+                } else {
685
+                    $result['description'] .= sprintf(
686
+                        '<p>%s %s</p>',
687
+                        sprintf(
688
+                            /* translators: 1: The amount of inactive themes. 2: The default theme for WordPress. 3: The currently active theme. */
689
+                            _n(
690
+                                'Your site has %1$d inactive theme, other than %2$s, the default WordPress theme, and %3$s, your active theme.',
691
+                                'Your site has %1$d inactive themes, other than %2$s, the default WordPress theme, and %3$s, your active theme.',
692
+                                $themes_inactive
693
+                            ),
694
+                            $themes_inactive,
695
+                            $default_theme ? $default_theme->name : WP_DEFAULT_THEME,
696
+                            $active_theme->name
697
+                        ),
698
+                        __( 'You should consider removing any unused themes to enhance your site&#8217;s security.' )
699
+                    );
700
+                }
701
+            }
702
+        }
703
+
704
+        // If no default Twenty* theme exists.
705
+        if ( ! $has_default_theme ) {
706
+            $result['status'] = 'recommended';
707
+
708
+            $result['label'] = __( 'Have a default theme available' );
709
+
710
+            $result['description'] .= sprintf(
711
+                '<p>%s</p>',
712
+                __( 'Your site does not have any default theme. Default themes are used by WordPress automatically if anything is wrong with your chosen theme.' )
713
+            );
714
+        }
715
+
716
+        return $result;
717
+    }
718
+
719
+    /**
720
+     * Test if the supplied PHP version is supported.
721
+     *
722
+     * @since 5.2.0
723
+     *
724
+     * @return array The test results.
725
+     */
726
+    public function get_test_php_version() {
727
+        $response = wp_check_php_version();
728
+
729
+        $result = array(
730
+            'label'       => sprintf(
731
+                /* translators: %s: The current PHP version. */
732
+                __( 'Your site is running the current version of PHP (%s)' ),
733
+                PHP_VERSION
734
+            ),
735
+            'status'      => 'good',
736
+            'badge'       => array(
737
+                'label' => __( 'Performance' ),
738
+                'color' => 'blue',
739
+            ),
740
+            'description' => sprintf(
741
+                '<p>%s</p>',
742
+                sprintf(
743
+                    /* translators: %s: The minimum recommended PHP version. */
744
+                    __( 'PHP is the programming language used to build and maintain WordPress. Newer versions of PHP are created with increased performance in mind, so you may see a positive effect on your site&#8217;s performance. The minimum recommended version of PHP is %s.' ),
745
+                    $response ? $response['recommended_version'] : ''
746
+                )
747
+            ),
748
+            'actions'     => sprintf(
749
+                '<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
750
+                esc_url( wp_get_update_php_url() ),
751
+                __( 'Learn more about updating PHP' ),
752
+                /* translators: Accessibility text. */
753
+                __( '(opens in a new tab)' )
754
+            ),
755
+            'test'        => 'php_version',
756
+        );
757
+
758
+        // PHP is up to date.
759
+        if ( ! $response || version_compare( PHP_VERSION, $response['recommended_version'], '>=' ) ) {
760
+            return $result;
761
+        }
762
+
763
+        // The PHP version is older than the recommended version, but still receiving active support.
764
+        if ( $response['is_supported'] ) {
765
+            $result['label'] = sprintf(
766
+                /* translators: %s: The server PHP version. */
767
+                __( 'Your site is running an older version of PHP (%s)' ),
768
+                PHP_VERSION
769
+            );
770
+            $result['status'] = 'recommended';
771
+
772
+            return $result;
773
+        }
774
+
775
+        // The PHP version is only receiving security fixes.
776
+        if ( $response['is_secure'] ) {
777
+            $result['label'] = sprintf(
778
+                /* translators: %s: The server PHP version. */
779
+                __( 'Your site is running an older version of PHP (%s), which should be updated' ),
780
+                PHP_VERSION
781
+            );
782
+            $result['status'] = 'recommended';
783
+
784
+            return $result;
785
+        }
786
+
787
+        // Anything no longer secure must be updated.
788
+        $result['label'] = sprintf(
789
+            /* translators: %s: The server PHP version. */
790
+            __( 'Your site is running an outdated version of PHP (%s), which requires an update' ),
791
+            PHP_VERSION
792
+        );
793
+        $result['status']         = 'critical';
794
+        $result['badge']['label'] = __( 'Security' );
795
+
796
+        return $result;
797
+    }
798
+
799
+    /**
800
+     * Check if the passed extension or function are available.
801
+     *
802
+     * Make the check for available PHP modules into a simple boolean operator for a cleaner test runner.
803
+     *
804
+     * @since 5.2.0
805
+     * @since 5.3.0 The `$constant_name` and `$class_name` parameters were added.
806
+     *
807
+     * @param string $extension_name Optional. The extension name to test. Default null.
808
+     * @param string $function_name  Optional. The function name to test. Default null.
809
+     * @param string $constant_name  Optional. The constant name to test for. Default null.
810
+     * @param string $class_name     Optional. The class name to test for. Default null.
811
+     * @return bool Whether or not the extension and function are available.
812
+     */
813
+    private function test_php_extension_availability( $extension_name = null, $function_name = null, $constant_name = null, $class_name = null ) {
814
+        // If no extension or function is passed, claim to fail testing, as we have nothing to test against.
815
+        if ( ! $extension_name && ! $function_name && ! $constant_name && ! $class_name ) {
816
+            return false;
817
+        }
818
+
819
+        if ( $extension_name && ! extension_loaded( $extension_name ) ) {
820
+            return false;
821
+        }
822
+
823
+        if ( $function_name && ! function_exists( $function_name ) ) {
824
+            return false;
825
+        }
826
+
827
+        if ( $constant_name && ! defined( $constant_name ) ) {
828
+            return false;
829
+        }
830
+
831
+        if ( $class_name && ! class_exists( $class_name ) ) {
832
+            return false;
833
+        }
834
+
835
+        return true;
836
+    }
837
+
838
+    /**
839
+     * Test if required PHP modules are installed on the host.
840
+     *
841
+     * This test builds on the recommendations made by the WordPress Hosting Team
842
+     * as seen at https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions
843
+     *
844
+     * @since 5.2.0
845
+     *
846
+     * @return array
847
+     */
848
+    public function get_test_php_extensions() {
849
+        $result = array(
850
+            'label'       => __( 'Required and recommended modules are installed' ),
851
+            'status'      => 'good',
852
+            'badge'       => array(
853
+                'label' => __( 'Performance' ),
854
+                'color' => 'blue',
855
+            ),
856
+            'description' => sprintf(
857
+                '<p>%s</p><p>%s</p>',
858
+                __( 'PHP modules perform most of the tasks on the server that make your site run. Any changes to these must be made by your server administrator.' ),
859
+                sprintf(
860
+                    /* translators: 1: Link to the hosting group page about recommended PHP modules. 2: Additional link attributes. 3: Accessibility text. */
861
+                    __( 'The WordPress Hosting Team maintains a list of those modules, both recommended and required, in <a href="%1$s" %2$s>the team handbook%3$s</a>.' ),
862
+                    /* translators: Localized team handbook, if one exists. */
863
+                    esc_url( __( 'https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions' ) ),
864
+                    'target="_blank" rel="noopener"',
865
+                    sprintf(
866
+                        ' <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span>',
867
+                        /* translators: Accessibility text. */
868
+                        __( '(opens in a new tab)' )
869
+                    )
870
+                )
871
+            ),
872
+            'actions'     => '',
873
+            'test'        => 'php_extensions',
874
+        );
875
+
876
+        $modules = array(
877
+            'curl'      => array(
878
+                'function' => 'curl_version',
879
+                'required' => false,
880
+            ),
881
+            'dom'       => array(
882
+                'class'    => 'DOMNode',
883
+                'required' => false,
884
+            ),
885
+            'exif'      => array(
886
+                'function' => 'exif_read_data',
887
+                'required' => false,
888
+            ),
889
+            'fileinfo'  => array(
890
+                'function' => 'finfo_file',
891
+                'required' => false,
892
+            ),
893
+            'hash'      => array(
894
+                'function' => 'hash',
895
+                'required' => false,
896
+            ),
897
+            'imagick'   => array(
898
+                'extension' => 'imagick',
899
+                'required'  => false,
900
+            ),
901
+            'json'      => array(
902
+                'function' => 'json_last_error',
903
+                'required' => true,
904
+            ),
905
+            'mbstring'  => array(
906
+                'function' => 'mb_check_encoding',
907
+                'required' => false,
908
+            ),
909
+            'mysqli'    => array(
910
+                'function' => 'mysqli_connect',
911
+                'required' => false,
912
+            ),
913
+            'libsodium' => array(
914
+                'constant'            => 'SODIUM_LIBRARY_VERSION',
915
+                'required'            => false,
916
+                'php_bundled_version' => '7.2.0',
917
+            ),
918
+            'openssl'   => array(
919
+                'function' => 'openssl_encrypt',
920
+                'required' => false,
921
+            ),
922
+            'pcre'      => array(
923
+                'function' => 'preg_match',
924
+                'required' => false,
925
+            ),
926
+            'mod_xml'   => array(
927
+                'extension' => 'libxml',
928
+                'required'  => false,
929
+            ),
930
+            'zip'       => array(
931
+                'class'    => 'ZipArchive',
932
+                'required' => false,
933
+            ),
934
+            'filter'    => array(
935
+                'function' => 'filter_list',
936
+                'required' => false,
937
+            ),
938
+            'gd'        => array(
939
+                'extension'    => 'gd',
940
+                'required'     => false,
941
+                'fallback_for' => 'imagick',
942
+            ),
943
+            'iconv'     => array(
944
+                'function' => 'iconv',
945
+                'required' => false,
946
+            ),
947
+            'intl'      => array(
948
+                'extension' => 'intl',
949
+                'required'  => false,
950
+            ),
951
+            'mcrypt'    => array(
952
+                'extension'    => 'mcrypt',
953
+                'required'     => false,
954
+                'fallback_for' => 'libsodium',
955
+            ),
956
+            'simplexml' => array(
957
+                'extension'    => 'simplexml',
958
+                'required'     => false,
959
+                'fallback_for' => 'mod_xml',
960
+            ),
961
+            'xmlreader' => array(
962
+                'extension'    => 'xmlreader',
963
+                'required'     => false,
964
+                'fallback_for' => 'mod_xml',
965
+            ),
966
+            'zlib'      => array(
967
+                'extension'    => 'zlib',
968
+                'required'     => false,
969
+                'fallback_for' => 'zip',
970
+            ),
971
+        );
972
+
973
+        /**
974
+         * An array representing all the modules we wish to test for.
975
+         *
976
+         * @since 5.2.0
977
+         * @since 5.3.0 The `$constant` and `$class` parameters were added.
978
+         *
979
+         * @param array $modules {
980
+         *     An associative array of modules to test for.
981
+         *
982
+         *     @type array ...$0 {
983
+         *         An associative array of module properties used during testing.
984
+         *         One of either `$function` or `$extension` must be provided, or they will fail by default.
985
+         *
986
+         *         @type string $function     Optional. A function name to test for the existence of.
987
+         *         @type string $extension    Optional. An extension to check if is loaded in PHP.
988
+         *         @type string $constant     Optional. A constant name to check for to verify an extension exists.
989
+         *         @type string $class        Optional. A class name to check for to verify an extension exists.
990
+         *         @type bool   $required     Is this a required feature or not.
991
+         *         @type string $fallback_for Optional. The module this module replaces as a fallback.
992
+         *     }
993
+         * }
994
+         */
995
+        $modules = apply_filters( 'site_status_test_php_modules', $modules );
996
+
997
+        $failures = array();
998
+
999
+        foreach ( $modules as $library => $module ) {
1000
+            $extension_name = ( isset( $module['extension'] ) ? $module['extension'] : null );
1001
+            $function_name  = ( isset( $module['function'] ) ? $module['function'] : null );
1002
+            $constant_name  = ( isset( $module['constant'] ) ? $module['constant'] : null );
1003
+            $class_name     = ( isset( $module['class'] ) ? $module['class'] : null );
1004
+
1005
+            // If this module is a fallback for another function, check if that other function passed.
1006
+            if ( isset( $module['fallback_for'] ) ) {
1007
+                /*
1008 1008
 				 * If that other function has a failure, mark this module as required for usual operations.
1009 1009
 				 * If that other function hasn't failed, skip this test as it's only a fallback.
1010 1010
 				 */
1011
-				if ( isset( $failures[ $module['fallback_for'] ] ) ) {
1012
-					$module['required'] = true;
1013
-				} else {
1014
-					continue;
1015
-				}
1016
-			}
1017
-
1018
-			if ( ! $this->test_php_extension_availability( $extension_name, $function_name, $constant_name, $class_name )
1019
-				&& ( ! isset( $module['php_bundled_version'] )
1020
-					|| version_compare( PHP_VERSION, $module['php_bundled_version'], '<' ) )
1021
-			) {
1022
-				if ( $module['required'] ) {
1023
-					$result['status'] = 'critical';
1024
-
1025
-					$class         = 'error';
1026
-					$screen_reader = __( 'Error' );
1027
-					$message       = sprintf(
1028
-						/* translators: %s: The module name. */
1029
-						__( 'The required module, %s, is not installed, or has been disabled.' ),
1030
-						$library
1031
-					);
1032
-				} else {
1033
-					$class         = 'warning';
1034
-					$screen_reader = __( 'Warning' );
1035
-					$message       = sprintf(
1036
-						/* translators: %s: The module name. */
1037
-						__( 'The optional module, %s, is not installed, or has been disabled.' ),
1038
-						$library
1039
-					);
1040
-				}
1041
-
1042
-				if ( ! $module['required'] && 'good' === $result['status'] ) {
1043
-					$result['status'] = 'recommended';
1044
-				}
1045
-
1046
-				$failures[ $library ] = "<span class='dashicons $class'><span class='screen-reader-text'>$screen_reader</span></span> $message";
1047
-			}
1048
-		}
1049
-
1050
-		if ( ! empty( $failures ) ) {
1051
-			$output = '<ul>';
1052
-
1053
-			foreach ( $failures as $failure ) {
1054
-				$output .= sprintf(
1055
-					'<li>%s</li>',
1056
-					$failure
1057
-				);
1058
-			}
1059
-
1060
-			$output .= '</ul>';
1061
-		}
1062
-
1063
-		if ( 'good' !== $result['status'] ) {
1064
-			if ( 'recommended' === $result['status'] ) {
1065
-				$result['label'] = __( 'One or more recommended modules are missing' );
1066
-			}
1067
-			if ( 'critical' === $result['status'] ) {
1068
-				$result['label'] = __( 'One or more required modules are missing' );
1069
-			}
1070
-
1071
-			$result['description'] .= $output;
1072
-		}
1073
-
1074
-		return $result;
1075
-	}
1076
-
1077
-	/**
1078
-	 * Test if the PHP default timezone is set to UTC.
1079
-	 *
1080
-	 * @since 5.3.1
1081
-	 *
1082
-	 * @return array The test results.
1083
-	 */
1084
-	public function get_test_php_default_timezone() {
1085
-		$result = array(
1086
-			'label'       => __( 'PHP default timezone is valid' ),
1087
-			'status'      => 'good',
1088
-			'badge'       => array(
1089
-				'label' => __( 'Performance' ),
1090
-				'color' => 'blue',
1091
-			),
1092
-			'description' => sprintf(
1093
-				'<p>%s</p>',
1094
-				__( 'PHP default timezone was configured by WordPress on loading. This is necessary for correct calculations of dates and times.' )
1095
-			),
1096
-			'actions'     => '',
1097
-			'test'        => 'php_default_timezone',
1098
-		);
1099
-
1100
-		if ( 'UTC' !== date_default_timezone_get() ) {
1101
-			$result['status'] = 'critical';
1102
-
1103
-			$result['label'] = __( 'PHP default timezone is invalid' );
1104
-
1105
-			$result['description'] = sprintf(
1106
-				'<p>%s</p>',
1107
-				sprintf(
1108
-					/* translators: %s: date_default_timezone_set() */
1109
-					__( 'PHP default timezone was changed after WordPress loading by a %s function call. This interferes with correct calculations of dates and times.' ),
1110
-					'<code>date_default_timezone_set()</code>'
1111
-				)
1112
-			);
1113
-		}
1114
-
1115
-		return $result;
1116
-	}
1117
-
1118
-	/**
1119
-	 * Test if there's an active PHP session that can affect loopback requests.
1120
-	 *
1121
-	 * @since 5.5.0
1122
-	 *
1123
-	 * @return array The test results.
1124
-	 */
1125
-	public function get_test_php_sessions() {
1126
-		$result = array(
1127
-			'label'       => __( 'No PHP sessions detected' ),
1128
-			'status'      => 'good',
1129
-			'badge'       => array(
1130
-				'label' => __( 'Performance' ),
1131
-				'color' => 'blue',
1132
-			),
1133
-			'description' => sprintf(
1134
-				'<p>%s</p>',
1135
-				sprintf(
1136
-					/* translators: 1: session_start(), 2: session_write_close() */
1137
-					__( 'PHP sessions created by a %1$s function call may interfere with REST API and loopback requests. An active session should be closed by %2$s before making any HTTP requests.' ),
1138
-					'<code>session_start()</code>',
1139
-					'<code>session_write_close()</code>'
1140
-				)
1141
-			),
1142
-			'test'        => 'php_sessions',
1143
-		);
1144
-
1145
-		if ( function_exists( 'session_status' ) && PHP_SESSION_ACTIVE === session_status() ) {
1146
-			$result['status'] = 'critical';
1147
-
1148
-			$result['label'] = __( 'An active PHP session was detected' );
1149
-
1150
-			$result['description'] = sprintf(
1151
-				'<p>%s</p>',
1152
-				sprintf(
1153
-					/* translators: 1: session_start(), 2: session_write_close() */
1154
-					__( 'A PHP session was created by a %1$s function call. This interferes with REST API and loopback requests. The session should be closed by %2$s before making any HTTP requests.' ),
1155
-					'<code>session_start()</code>',
1156
-					'<code>session_write_close()</code>'
1157
-				)
1158
-			);
1159
-		}
1160
-
1161
-		return $result;
1162
-	}
1163
-
1164
-	/**
1165
-	 * Test if the SQL server is up to date.
1166
-	 *
1167
-	 * @since 5.2.0
1168
-	 *
1169
-	 * @return array The test results.
1170
-	 */
1171
-	public function get_test_sql_server() {
1172
-		if ( ! $this->mysql_server_version ) {
1173
-			$this->prepare_sql_data();
1174
-		}
1175
-
1176
-		$result = array(
1177
-			'label'       => __( 'SQL server is up to date' ),
1178
-			'status'      => 'good',
1179
-			'badge'       => array(
1180
-				'label' => __( 'Performance' ),
1181
-				'color' => 'blue',
1182
-			),
1183
-			'description' => sprintf(
1184
-				'<p>%s</p>',
1185
-				__( 'The SQL server is a required piece of software for the database WordPress uses to store all your site&#8217;s content and settings.' )
1186
-			),
1187
-			'actions'     => sprintf(
1188
-				'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1189
-				/* translators: Localized version of WordPress requirements if one exists. */
1190
-				esc_url( __( 'https://wordpress.org/about/requirements/' ) ),
1191
-				__( 'Learn more about what WordPress requires to run.' ),
1192
-				/* translators: Accessibility text. */
1193
-				__( '(opens in a new tab)' )
1194
-			),
1195
-			'test'        => 'sql_server',
1196
-		);
1197
-
1198
-		$db_dropin = file_exists( WP_CONTENT_DIR . '/db.php' );
1199
-
1200
-		if ( ! $this->mysql_rec_version_check ) {
1201
-			$result['status'] = 'recommended';
1202
-
1203
-			$result['label'] = __( 'Outdated SQL server' );
1204
-
1205
-			$result['description'] .= sprintf(
1206
-				'<p>%s</p>',
1207
-				sprintf(
1208
-					/* translators: 1: The database engine in use (MySQL or MariaDB). 2: Database server recommended version number. */
1209
-					__( 'For optimal performance and security reasons, you should consider running %1$s version %2$s or higher. Contact your web hosting company to correct this.' ),
1210
-					( $this->is_mariadb ? 'MariaDB' : 'MySQL' ),
1211
-					$this->health_check_mysql_rec_version
1212
-				)
1213
-			);
1214
-		}
1215
-
1216
-		if ( ! $this->mysql_min_version_check ) {
1217
-			$result['status'] = 'critical';
1218
-
1219
-			$result['label']          = __( 'Severely outdated SQL server' );
1220
-			$result['badge']['label'] = __( 'Security' );
1221
-
1222
-			$result['description'] .= sprintf(
1223
-				'<p>%s</p>',
1224
-				sprintf(
1225
-					/* translators: 1: The database engine in use (MySQL or MariaDB). 2: Database server minimum version number. */
1226
-					__( 'WordPress requires %1$s version %2$s or higher. Contact your web hosting company to correct this.' ),
1227
-					( $this->is_mariadb ? 'MariaDB' : 'MySQL' ),
1228
-					$this->health_check_mysql_required_version
1229
-				)
1230
-			);
1231
-		}
1232
-
1233
-		if ( $db_dropin ) {
1234
-			$result['description'] .= sprintf(
1235
-				'<p>%s</p>',
1236
-				wp_kses(
1237
-					sprintf(
1238
-						/* translators: 1: The name of the drop-in. 2: The name of the database engine. */
1239
-						__( 'You are using a %1$s drop-in which might mean that a %2$s database is not being used.' ),
1240
-						'<code>wp-content/db.php</code>',
1241
-						( $this->is_mariadb ? 'MariaDB' : 'MySQL' )
1242
-					),
1243
-					array(
1244
-						'code' => true,
1245
-					)
1246
-				)
1247
-			);
1248
-		}
1249
-
1250
-		return $result;
1251
-	}
1252
-
1253
-	/**
1254
-	 * Test if the database server is capable of using utf8mb4.
1255
-	 *
1256
-	 * @since 5.2.0
1257
-	 *
1258
-	 * @return array The test results.
1259
-	 */
1260
-	public function get_test_utf8mb4_support() {
1261
-		global $wpdb;
1262
-
1263
-		if ( ! $this->mysql_server_version ) {
1264
-			$this->prepare_sql_data();
1265
-		}
1266
-
1267
-		$result = array(
1268
-			'label'       => __( 'UTF8MB4 is supported' ),
1269
-			'status'      => 'good',
1270
-			'badge'       => array(
1271
-				'label' => __( 'Performance' ),
1272
-				'color' => 'blue',
1273
-			),
1274
-			'description' => sprintf(
1275
-				'<p>%s</p>',
1276
-				__( 'UTF8MB4 is the character set WordPress prefers for database storage because it safely supports the widest set of characters and encodings, including Emoji, enabling better support for non-English languages.' )
1277
-			),
1278
-			'actions'     => '',
1279
-			'test'        => 'utf8mb4_support',
1280
-		);
1281
-
1282
-		if ( ! $this->is_mariadb ) {
1283
-			if ( version_compare( $this->mysql_server_version, '5.5.3', '<' ) ) {
1284
-				$result['status'] = 'recommended';
1285
-
1286
-				$result['label'] = __( 'utf8mb4 requires a MySQL update' );
1287
-
1288
-				$result['description'] .= sprintf(
1289
-					'<p>%s</p>',
1290
-					sprintf(
1291
-						/* translators: %s: Version number. */
1292
-						__( 'WordPress&#8217; utf8mb4 support requires MySQL version %s or greater. Please contact your server administrator.' ),
1293
-						'5.5.3'
1294
-					)
1295
-				);
1296
-			} else {
1297
-				$result['description'] .= sprintf(
1298
-					'<p>%s</p>',
1299
-					__( 'Your MySQL version supports utf8mb4.' )
1300
-				);
1301
-			}
1302
-		} else { // MariaDB introduced utf8mb4 support in 5.5.0.
1303
-			if ( version_compare( $this->mysql_server_version, '5.5.0', '<' ) ) {
1304
-				$result['status'] = 'recommended';
1305
-
1306
-				$result['label'] = __( 'utf8mb4 requires a MariaDB update' );
1307
-
1308
-				$result['description'] .= sprintf(
1309
-					'<p>%s</p>',
1310
-					sprintf(
1311
-						/* translators: %s: Version number. */
1312
-						__( 'WordPress&#8217; utf8mb4 support requires MariaDB version %s or greater. Please contact your server administrator.' ),
1313
-						'5.5.0'
1314
-					)
1315
-				);
1316
-			} else {
1317
-				$result['description'] .= sprintf(
1318
-					'<p>%s</p>',
1319
-					__( 'Your MariaDB version supports utf8mb4.' )
1320
-				);
1321
-			}
1322
-		}
1323
-
1324
-		if ( $wpdb->use_mysqli ) {
1325
-			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
1326
-			$mysql_client_version = mysqli_get_client_info();
1327
-		} else {
1328
-			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
1329
-			$mysql_client_version = mysql_get_client_info();
1330
-		}
1331
-
1332
-		/*
1011
+                if ( isset( $failures[ $module['fallback_for'] ] ) ) {
1012
+                    $module['required'] = true;
1013
+                } else {
1014
+                    continue;
1015
+                }
1016
+            }
1017
+
1018
+            if ( ! $this->test_php_extension_availability( $extension_name, $function_name, $constant_name, $class_name )
1019
+                && ( ! isset( $module['php_bundled_version'] )
1020
+                    || version_compare( PHP_VERSION, $module['php_bundled_version'], '<' ) )
1021
+            ) {
1022
+                if ( $module['required'] ) {
1023
+                    $result['status'] = 'critical';
1024
+
1025
+                    $class         = 'error';
1026
+                    $screen_reader = __( 'Error' );
1027
+                    $message       = sprintf(
1028
+                        /* translators: %s: The module name. */
1029
+                        __( 'The required module, %s, is not installed, or has been disabled.' ),
1030
+                        $library
1031
+                    );
1032
+                } else {
1033
+                    $class         = 'warning';
1034
+                    $screen_reader = __( 'Warning' );
1035
+                    $message       = sprintf(
1036
+                        /* translators: %s: The module name. */
1037
+                        __( 'The optional module, %s, is not installed, or has been disabled.' ),
1038
+                        $library
1039
+                    );
1040
+                }
1041
+
1042
+                if ( ! $module['required'] && 'good' === $result['status'] ) {
1043
+                    $result['status'] = 'recommended';
1044
+                }
1045
+
1046
+                $failures[ $library ] = "<span class='dashicons $class'><span class='screen-reader-text'>$screen_reader</span></span> $message";
1047
+            }
1048
+        }
1049
+
1050
+        if ( ! empty( $failures ) ) {
1051
+            $output = '<ul>';
1052
+
1053
+            foreach ( $failures as $failure ) {
1054
+                $output .= sprintf(
1055
+                    '<li>%s</li>',
1056
+                    $failure
1057
+                );
1058
+            }
1059
+
1060
+            $output .= '</ul>';
1061
+        }
1062
+
1063
+        if ( 'good' !== $result['status'] ) {
1064
+            if ( 'recommended' === $result['status'] ) {
1065
+                $result['label'] = __( 'One or more recommended modules are missing' );
1066
+            }
1067
+            if ( 'critical' === $result['status'] ) {
1068
+                $result['label'] = __( 'One or more required modules are missing' );
1069
+            }
1070
+
1071
+            $result['description'] .= $output;
1072
+        }
1073
+
1074
+        return $result;
1075
+    }
1076
+
1077
+    /**
1078
+     * Test if the PHP default timezone is set to UTC.
1079
+     *
1080
+     * @since 5.3.1
1081
+     *
1082
+     * @return array The test results.
1083
+     */
1084
+    public function get_test_php_default_timezone() {
1085
+        $result = array(
1086
+            'label'       => __( 'PHP default timezone is valid' ),
1087
+            'status'      => 'good',
1088
+            'badge'       => array(
1089
+                'label' => __( 'Performance' ),
1090
+                'color' => 'blue',
1091
+            ),
1092
+            'description' => sprintf(
1093
+                '<p>%s</p>',
1094
+                __( 'PHP default timezone was configured by WordPress on loading. This is necessary for correct calculations of dates and times.' )
1095
+            ),
1096
+            'actions'     => '',
1097
+            'test'        => 'php_default_timezone',
1098
+        );
1099
+
1100
+        if ( 'UTC' !== date_default_timezone_get() ) {
1101
+            $result['status'] = 'critical';
1102
+
1103
+            $result['label'] = __( 'PHP default timezone is invalid' );
1104
+
1105
+            $result['description'] = sprintf(
1106
+                '<p>%s</p>',
1107
+                sprintf(
1108
+                    /* translators: %s: date_default_timezone_set() */
1109
+                    __( 'PHP default timezone was changed after WordPress loading by a %s function call. This interferes with correct calculations of dates and times.' ),
1110
+                    '<code>date_default_timezone_set()</code>'
1111
+                )
1112
+            );
1113
+        }
1114
+
1115
+        return $result;
1116
+    }
1117
+
1118
+    /**
1119
+     * Test if there's an active PHP session that can affect loopback requests.
1120
+     *
1121
+     * @since 5.5.0
1122
+     *
1123
+     * @return array The test results.
1124
+     */
1125
+    public function get_test_php_sessions() {
1126
+        $result = array(
1127
+            'label'       => __( 'No PHP sessions detected' ),
1128
+            'status'      => 'good',
1129
+            'badge'       => array(
1130
+                'label' => __( 'Performance' ),
1131
+                'color' => 'blue',
1132
+            ),
1133
+            'description' => sprintf(
1134
+                '<p>%s</p>',
1135
+                sprintf(
1136
+                    /* translators: 1: session_start(), 2: session_write_close() */
1137
+                    __( 'PHP sessions created by a %1$s function call may interfere with REST API and loopback requests. An active session should be closed by %2$s before making any HTTP requests.' ),
1138
+                    '<code>session_start()</code>',
1139
+                    '<code>session_write_close()</code>'
1140
+                )
1141
+            ),
1142
+            'test'        => 'php_sessions',
1143
+        );
1144
+
1145
+        if ( function_exists( 'session_status' ) && PHP_SESSION_ACTIVE === session_status() ) {
1146
+            $result['status'] = 'critical';
1147
+
1148
+            $result['label'] = __( 'An active PHP session was detected' );
1149
+
1150
+            $result['description'] = sprintf(
1151
+                '<p>%s</p>',
1152
+                sprintf(
1153
+                    /* translators: 1: session_start(), 2: session_write_close() */
1154
+                    __( 'A PHP session was created by a %1$s function call. This interferes with REST API and loopback requests. The session should be closed by %2$s before making any HTTP requests.' ),
1155
+                    '<code>session_start()</code>',
1156
+                    '<code>session_write_close()</code>'
1157
+                )
1158
+            );
1159
+        }
1160
+
1161
+        return $result;
1162
+    }
1163
+
1164
+    /**
1165
+     * Test if the SQL server is up to date.
1166
+     *
1167
+     * @since 5.2.0
1168
+     *
1169
+     * @return array The test results.
1170
+     */
1171
+    public function get_test_sql_server() {
1172
+        if ( ! $this->mysql_server_version ) {
1173
+            $this->prepare_sql_data();
1174
+        }
1175
+
1176
+        $result = array(
1177
+            'label'       => __( 'SQL server is up to date' ),
1178
+            'status'      => 'good',
1179
+            'badge'       => array(
1180
+                'label' => __( 'Performance' ),
1181
+                'color' => 'blue',
1182
+            ),
1183
+            'description' => sprintf(
1184
+                '<p>%s</p>',
1185
+                __( 'The SQL server is a required piece of software for the database WordPress uses to store all your site&#8217;s content and settings.' )
1186
+            ),
1187
+            'actions'     => sprintf(
1188
+                '<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1189
+                /* translators: Localized version of WordPress requirements if one exists. */
1190
+                esc_url( __( 'https://wordpress.org/about/requirements/' ) ),
1191
+                __( 'Learn more about what WordPress requires to run.' ),
1192
+                /* translators: Accessibility text. */
1193
+                __( '(opens in a new tab)' )
1194
+            ),
1195
+            'test'        => 'sql_server',
1196
+        );
1197
+
1198
+        $db_dropin = file_exists( WP_CONTENT_DIR . '/db.php' );
1199
+
1200
+        if ( ! $this->mysql_rec_version_check ) {
1201
+            $result['status'] = 'recommended';
1202
+
1203
+            $result['label'] = __( 'Outdated SQL server' );
1204
+
1205
+            $result['description'] .= sprintf(
1206
+                '<p>%s</p>',
1207
+                sprintf(
1208
+                    /* translators: 1: The database engine in use (MySQL or MariaDB). 2: Database server recommended version number. */
1209
+                    __( 'For optimal performance and security reasons, you should consider running %1$s version %2$s or higher. Contact your web hosting company to correct this.' ),
1210
+                    ( $this->is_mariadb ? 'MariaDB' : 'MySQL' ),
1211
+                    $this->health_check_mysql_rec_version
1212
+                )
1213
+            );
1214
+        }
1215
+
1216
+        if ( ! $this->mysql_min_version_check ) {
1217
+            $result['status'] = 'critical';
1218
+
1219
+            $result['label']          = __( 'Severely outdated SQL server' );
1220
+            $result['badge']['label'] = __( 'Security' );
1221
+
1222
+            $result['description'] .= sprintf(
1223
+                '<p>%s</p>',
1224
+                sprintf(
1225
+                    /* translators: 1: The database engine in use (MySQL or MariaDB). 2: Database server minimum version number. */
1226
+                    __( 'WordPress requires %1$s version %2$s or higher. Contact your web hosting company to correct this.' ),
1227
+                    ( $this->is_mariadb ? 'MariaDB' : 'MySQL' ),
1228
+                    $this->health_check_mysql_required_version
1229
+                )
1230
+            );
1231
+        }
1232
+
1233
+        if ( $db_dropin ) {
1234
+            $result['description'] .= sprintf(
1235
+                '<p>%s</p>',
1236
+                wp_kses(
1237
+                    sprintf(
1238
+                        /* translators: 1: The name of the drop-in. 2: The name of the database engine. */
1239
+                        __( 'You are using a %1$s drop-in which might mean that a %2$s database is not being used.' ),
1240
+                        '<code>wp-content/db.php</code>',
1241
+                        ( $this->is_mariadb ? 'MariaDB' : 'MySQL' )
1242
+                    ),
1243
+                    array(
1244
+                        'code' => true,
1245
+                    )
1246
+                )
1247
+            );
1248
+        }
1249
+
1250
+        return $result;
1251
+    }
1252
+
1253
+    /**
1254
+     * Test if the database server is capable of using utf8mb4.
1255
+     *
1256
+     * @since 5.2.0
1257
+     *
1258
+     * @return array The test results.
1259
+     */
1260
+    public function get_test_utf8mb4_support() {
1261
+        global $wpdb;
1262
+
1263
+        if ( ! $this->mysql_server_version ) {
1264
+            $this->prepare_sql_data();
1265
+        }
1266
+
1267
+        $result = array(
1268
+            'label'       => __( 'UTF8MB4 is supported' ),
1269
+            'status'      => 'good',
1270
+            'badge'       => array(
1271
+                'label' => __( 'Performance' ),
1272
+                'color' => 'blue',
1273
+            ),
1274
+            'description' => sprintf(
1275
+                '<p>%s</p>',
1276
+                __( 'UTF8MB4 is the character set WordPress prefers for database storage because it safely supports the widest set of characters and encodings, including Emoji, enabling better support for non-English languages.' )
1277
+            ),
1278
+            'actions'     => '',
1279
+            'test'        => 'utf8mb4_support',
1280
+        );
1281
+
1282
+        if ( ! $this->is_mariadb ) {
1283
+            if ( version_compare( $this->mysql_server_version, '5.5.3', '<' ) ) {
1284
+                $result['status'] = 'recommended';
1285
+
1286
+                $result['label'] = __( 'utf8mb4 requires a MySQL update' );
1287
+
1288
+                $result['description'] .= sprintf(
1289
+                    '<p>%s</p>',
1290
+                    sprintf(
1291
+                        /* translators: %s: Version number. */
1292
+                        __( 'WordPress&#8217; utf8mb4 support requires MySQL version %s or greater. Please contact your server administrator.' ),
1293
+                        '5.5.3'
1294
+                    )
1295
+                );
1296
+            } else {
1297
+                $result['description'] .= sprintf(
1298
+                    '<p>%s</p>',
1299
+                    __( 'Your MySQL version supports utf8mb4.' )
1300
+                );
1301
+            }
1302
+        } else { // MariaDB introduced utf8mb4 support in 5.5.0.
1303
+            if ( version_compare( $this->mysql_server_version, '5.5.0', '<' ) ) {
1304
+                $result['status'] = 'recommended';
1305
+
1306
+                $result['label'] = __( 'utf8mb4 requires a MariaDB update' );
1307
+
1308
+                $result['description'] .= sprintf(
1309
+                    '<p>%s</p>',
1310
+                    sprintf(
1311
+                        /* translators: %s: Version number. */
1312
+                        __( 'WordPress&#8217; utf8mb4 support requires MariaDB version %s or greater. Please contact your server administrator.' ),
1313
+                        '5.5.0'
1314
+                    )
1315
+                );
1316
+            } else {
1317
+                $result['description'] .= sprintf(
1318
+                    '<p>%s</p>',
1319
+                    __( 'Your MariaDB version supports utf8mb4.' )
1320
+                );
1321
+            }
1322
+        }
1323
+
1324
+        if ( $wpdb->use_mysqli ) {
1325
+            // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
1326
+            $mysql_client_version = mysqli_get_client_info();
1327
+        } else {
1328
+            // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
1329
+            $mysql_client_version = mysql_get_client_info();
1330
+        }
1331
+
1332
+        /*
1333 1333
 		 * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
1334 1334
 		 * mysqlnd has supported utf8mb4 since 5.0.9.
1335 1335
 		 */
1336
-		if ( false !== strpos( $mysql_client_version, 'mysqlnd' ) ) {
1337
-			$mysql_client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $mysql_client_version );
1338
-			if ( version_compare( $mysql_client_version, '5.0.9', '<' ) ) {
1339
-				$result['status'] = 'recommended';
1340
-
1341
-				$result['label'] = __( 'utf8mb4 requires a newer client library' );
1342
-
1343
-				$result['description'] .= sprintf(
1344
-					'<p>%s</p>',
1345
-					sprintf(
1346
-						/* translators: 1: Name of the library, 2: Number of version. */
1347
-						__( 'WordPress&#8217; utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer. Please contact your server administrator.' ),
1348
-						'mysqlnd',
1349
-						'5.0.9'
1350
-					)
1351
-				);
1352
-			}
1353
-		} else {
1354
-			if ( version_compare( $mysql_client_version, '5.5.3', '<' ) ) {
1355
-				$result['status'] = 'recommended';
1356
-
1357
-				$result['label'] = __( 'utf8mb4 requires a newer client library' );
1358
-
1359
-				$result['description'] .= sprintf(
1360
-					'<p>%s</p>',
1361
-					sprintf(
1362
-						/* translators: 1: Name of the library, 2: Number of version. */
1363
-						__( 'WordPress&#8217; utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer. Please contact your server administrator.' ),
1364
-						'libmysql',
1365
-						'5.5.3'
1366
-					)
1367
-				);
1368
-			}
1369
-		}
1370
-
1371
-		return $result;
1372
-	}
1373
-
1374
-	/**
1375
-	 * Test if the site can communicate with WordPress.org.
1376
-	 *
1377
-	 * @since 5.2.0
1378
-	 *
1379
-	 * @return array The test results.
1380
-	 */
1381
-	public function get_test_dotorg_communication() {
1382
-		$result = array(
1383
-			'label'       => __( 'Can communicate with WordPress.org' ),
1384
-			'status'      => '',
1385
-			'badge'       => array(
1386
-				'label' => __( 'Security' ),
1387
-				'color' => 'blue',
1388
-			),
1389
-			'description' => sprintf(
1390
-				'<p>%s</p>',
1391
-				__( 'Communicating with the WordPress servers is used to check for new versions, and to both install and update WordPress core, themes or plugins.' )
1392
-			),
1393
-			'actions'     => '',
1394
-			'test'        => 'dotorg_communication',
1395
-		);
1396
-
1397
-		$wp_dotorg = wp_remote_get(
1398
-			'https://api.wordpress.org',
1399
-			array(
1400
-				'timeout' => 10,
1401
-			)
1402
-		);
1403
-		if ( ! is_wp_error( $wp_dotorg ) ) {
1404
-			$result['status'] = 'good';
1405
-		} else {
1406
-			$result['status'] = 'critical';
1407
-
1408
-			$result['label'] = __( 'Could not reach WordPress.org' );
1409
-
1410
-			$result['description'] .= sprintf(
1411
-				'<p>%s</p>',
1412
-				sprintf(
1413
-					'<span class="error"><span class="screen-reader-text">%s</span></span> %s',
1414
-					__( 'Error' ),
1415
-					sprintf(
1416
-						/* translators: 1: The IP address WordPress.org resolves to. 2: The error returned by the lookup. */
1417
-						__( 'Your site is unable to reach WordPress.org at %1$s, and returned the error: %2$s' ),
1418
-						gethostbyname( 'api.wordpress.org' ),
1419
-						$wp_dotorg->get_error_message()
1420
-					)
1421
-				)
1422
-			);
1423
-
1424
-			$result['actions'] = sprintf(
1425
-				'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1426
-				/* translators: Localized Support reference. */
1427
-				esc_url( __( 'https://wordpress.org/support' ) ),
1428
-				__( 'Get help resolving this issue.' ),
1429
-				/* translators: Accessibility text. */
1430
-				__( '(opens in a new tab)' )
1431
-			);
1432
-		}
1433
-
1434
-		return $result;
1435
-	}
1436
-
1437
-	/**
1438
-	 * Test if debug information is enabled.
1439
-	 *
1440
-	 * When WP_DEBUG is enabled, errors and information may be disclosed to site visitors,
1441
-	 * or logged to a publicly accessible file.
1442
-	 *
1443
-	 * Debugging is also frequently left enabled after looking for errors on a site,
1444
-	 * as site owners do not understand the implications of this.
1445
-	 *
1446
-	 * @since 5.2.0
1447
-	 *
1448
-	 * @return array The test results.
1449
-	 */
1450
-	public function get_test_is_in_debug_mode() {
1451
-		$result = array(
1452
-			'label'       => __( 'Your site is not set to output debug information' ),
1453
-			'status'      => 'good',
1454
-			'badge'       => array(
1455
-				'label' => __( 'Security' ),
1456
-				'color' => 'blue',
1457
-			),
1458
-			'description' => sprintf(
1459
-				'<p>%s</p>',
1460
-				__( 'Debug mode is often enabled to gather more details about an error or site failure, but may contain sensitive information which should not be available on a publicly available website.' )
1461
-			),
1462
-			'actions'     => sprintf(
1463
-				'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1464
-				/* translators: Documentation explaining debugging in WordPress. */
1465
-				esc_url( __( 'https://wordpress.org/support/article/debugging-in-wordpress/' ) ),
1466
-				__( 'Learn more about debugging in WordPress.' ),
1467
-				/* translators: Accessibility text. */
1468
-				__( '(opens in a new tab)' )
1469
-			),
1470
-			'test'        => 'is_in_debug_mode',
1471
-		);
1472
-
1473
-		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
1474
-			if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
1475
-				$result['label'] = __( 'Your site is set to log errors to a potentially public file' );
1476
-
1477
-				$result['status'] = ( 0 === strpos( ini_get( 'error_log' ), ABSPATH ) ) ? 'critical' : 'recommended';
1478
-
1479
-				$result['description'] .= sprintf(
1480
-					'<p>%s</p>',
1481
-					sprintf(
1482
-						/* translators: %s: WP_DEBUG_LOG */
1483
-						__( 'The value, %s, has been added to this website&#8217;s configuration file. This means any errors on the site will be written to a file which is potentially available to all users.' ),
1484
-						'<code>WP_DEBUG_LOG</code>'
1485
-					)
1486
-				);
1487
-			}
1488
-
1489
-			if ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) {
1490
-				$result['label'] = __( 'Your site is set to display errors to site visitors' );
1491
-
1492
-				$result['status'] = 'critical';
1493
-
1494
-				// On development environments, set the status to recommended.
1495
-				if ( $this->is_development_environment() ) {
1496
-					$result['status'] = 'recommended';
1497
-				}
1498
-
1499
-				$result['description'] .= sprintf(
1500
-					'<p>%s</p>',
1501
-					sprintf(
1502
-						/* translators: 1: WP_DEBUG_DISPLAY, 2: WP_DEBUG */
1503
-						__( 'The value, %1$s, has either been enabled by %2$s or added to your configuration file. This will make errors display on the front end of your site.' ),
1504
-						'<code>WP_DEBUG_DISPLAY</code>',
1505
-						'<code>WP_DEBUG</code>'
1506
-					)
1507
-				);
1508
-			}
1509
-		}
1510
-
1511
-		return $result;
1512
-	}
1513
-
1514
-	/**
1515
-	 * Test if your site is serving content over HTTPS.
1516
-	 *
1517
-	 * Many sites have varying degrees of HTTPS support, the most common of which is sites that have it
1518
-	 * enabled, but only if you visit the right site address.
1519
-	 *
1520
-	 * @since 5.2.0
1521
-	 * @since 5.7.0 Updated to rely on {@see wp_is_using_https()} and {@see wp_is_https_supported()}.
1522
-	 *
1523
-	 * @return array The test results.
1524
-	 */
1525
-	public function get_test_https_status() {
1526
-		// Enforce fresh HTTPS detection results. This is normally invoked by using cron,
1527
-		// but for Site Health it should always rely on the latest results.
1528
-		wp_update_https_detection_errors();
1529
-
1530
-		$default_update_url = wp_get_default_update_https_url();
1531
-
1532
-		$result = array(
1533
-			'label'       => __( 'Your website is using an active HTTPS connection' ),
1534
-			'status'      => 'good',
1535
-			'badge'       => array(
1536
-				'label' => __( 'Security' ),
1537
-				'color' => 'blue',
1538
-			),
1539
-			'description' => sprintf(
1540
-				'<p>%s</p>',
1541
-				__( 'An HTTPS connection is a more secure way of browsing the web. Many services now have HTTPS as a requirement. HTTPS allows you to take advantage of new features that can increase site speed, improve search rankings, and gain the trust of your visitors by helping to protect their online privacy.' )
1542
-			),
1543
-			'actions'     => sprintf(
1544
-				'<p><a href="%s" target="_blank" rel="noopener">%s<span class="screen-reader-text"> %s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1545
-				esc_url( $default_update_url ),
1546
-				__( 'Learn more about why you should use HTTPS' ),
1547
-				/* translators: Accessibility text. */
1548
-				__( '(opens in a new tab)' )
1549
-			),
1550
-			'test'        => 'https_status',
1551
-		);
1552
-
1553
-		if ( ! wp_is_using_https() ) {
1554
-			// If the website is not using HTTPS, provide more information
1555
-			// about whether it is supported and how it can be enabled.
1556
-			$result['status'] = 'recommended';
1557
-			$result['label']  = __( 'Your website does not use HTTPS' );
1558
-
1559
-			if ( wp_is_site_url_using_https() ) {
1560
-				if ( is_ssl() ) {
1561
-					$result['description'] = sprintf(
1562
-						'<p>%s</p>',
1563
-						sprintf(
1564
-							/* translators: %s: URL to Settings > General > Site Address. */
1565
-							__( 'You are accessing this website using HTTPS, but your <a href="%s">Site Address</a> is not set up to use HTTPS by default.' ),
1566
-							esc_url( admin_url( 'options-general.php' ) . '#home' )
1567
-						)
1568
-					);
1569
-				} else {
1570
-					$result['description'] = sprintf(
1571
-						'<p>%s</p>',
1572
-						sprintf(
1573
-							/* translators: %s: URL to Settings > General > Site Address. */
1574
-							__( 'Your <a href="%s">Site Address</a> is not set up to use HTTPS.' ),
1575
-							esc_url( admin_url( 'options-general.php' ) . '#home' )
1576
-						)
1577
-					);
1578
-				}
1579
-			} else {
1580
-				if ( is_ssl() ) {
1581
-					$result['description'] = sprintf(
1582
-						'<p>%s</p>',
1583
-						sprintf(
1584
-							/* translators: 1: URL to Settings > General > WordPress Address, 2: URL to Settings > General > Site Address. */
1585
-							__( 'You are accessing this website using HTTPS, but your <a href="%1$s">WordPress Address</a> and <a href="%2$s">Site Address</a> are not set up to use HTTPS by default.' ),
1586
-							esc_url( admin_url( 'options-general.php' ) . '#siteurl' ),
1587
-							esc_url( admin_url( 'options-general.php' ) . '#home' )
1588
-						)
1589
-					);
1590
-				} else {
1591
-					$result['description'] = sprintf(
1592
-						'<p>%s</p>',
1593
-						sprintf(
1594
-							/* translators: 1: URL to Settings > General > WordPress Address, 2: URL to Settings > General > Site Address. */
1595
-							__( 'Your <a href="%1$s">WordPress Address</a> and <a href="%2$s">Site Address</a> are not set up to use HTTPS.' ),
1596
-							esc_url( admin_url( 'options-general.php' ) . '#siteurl' ),
1597
-							esc_url( admin_url( 'options-general.php' ) . '#home' )
1598
-						)
1599
-					);
1600
-				}
1601
-			}
1602
-
1603
-			if ( wp_is_https_supported() ) {
1604
-				$result['description'] .= sprintf(
1605
-					'<p>%s</p>',
1606
-					__( 'HTTPS is already supported for your website.' )
1607
-				);
1608
-
1609
-				if ( defined( 'WP_HOME' ) || defined( 'WP_SITEURL' ) ) {
1610
-					$result['description'] .= sprintf(
1611
-						'<p>%s</p>',
1612
-						sprintf(
1613
-							/* translators: 1: wp-config.php, 2: WP_HOME, 3: WP_SITEURL */
1614
-							__( 'However, your WordPress Address is currently controlled by a PHP constant and therefore cannot be updated. You need to edit your %1$s and remove or update the definitions of %2$s and %3$s.' ),
1615
-							'<code>wp-config.php</code>',
1616
-							'<code>WP_HOME</code>',
1617
-							'<code>WP_SITEURL</code>'
1618
-						)
1619
-					);
1620
-				} elseif ( current_user_can( 'update_https' ) ) {
1621
-					$default_direct_update_url = add_query_arg( 'action', 'update_https', wp_nonce_url( admin_url( 'site-health.php' ), 'wp_update_https' ) );
1622
-					$direct_update_url         = wp_get_direct_update_https_url();
1623
-
1624
-					if ( ! empty( $direct_update_url ) ) {
1625
-						$result['actions'] = sprintf(
1626
-							'<p class="button-container"><a class="button button-primary" href="%1$s" target="_blank" rel="noopener">%2$s<span class="screen-reader-text"> %3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1627
-							esc_url( $direct_update_url ),
1628
-							__( 'Update your site to use HTTPS' ),
1629
-							/* translators: Accessibility text. */
1630
-							__( '(opens in a new tab)' )
1631
-						);
1632
-					} else {
1633
-						$result['actions'] = sprintf(
1634
-							'<p class="button-container"><a class="button button-primary" href="%1$s">%2$s</a></p>',
1635
-							esc_url( $default_direct_update_url ),
1636
-							__( 'Update your site to use HTTPS' )
1637
-						);
1638
-					}
1639
-				}
1640
-			} else {
1641
-				// If host-specific "Update HTTPS" URL is provided, include a link.
1642
-				$update_url = wp_get_update_https_url();
1643
-				if ( $update_url !== $default_update_url ) {
1644
-					$result['description'] .= sprintf(
1645
-						'<p><a href="%s" target="_blank" rel="noopener">%s<span class="screen-reader-text"> %s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1646
-						esc_url( $update_url ),
1647
-						__( 'Talk to your web host about supporting HTTPS for your website.' ),
1648
-						/* translators: Accessibility text. */
1649
-						__( '(opens in a new tab)' )
1650
-					);
1651
-				} else {
1652
-					$result['description'] .= sprintf(
1653
-						'<p>%s</p>',
1654
-						__( 'Talk to your web host about supporting HTTPS for your website.' )
1655
-					);
1656
-				}
1657
-			}
1658
-		}
1659
-
1660
-		return $result;
1661
-	}
1662
-
1663
-	/**
1664
-	 * Check if the HTTP API can handle SSL/TLS requests.
1665
-	 *
1666
-	 * @since 5.2.0
1667
-	 *
1668
-	 * @return array The test results.
1669
-	 */
1670
-	public function get_test_ssl_support() {
1671
-		$result = array(
1672
-			'label'       => '',
1673
-			'status'      => '',
1674
-			'badge'       => array(
1675
-				'label' => __( 'Security' ),
1676
-				'color' => 'blue',
1677
-			),
1678
-			'description' => sprintf(
1679
-				'<p>%s</p>',
1680
-				__( 'Securely communicating between servers are needed for transactions such as fetching files, conducting sales on store sites, and much more.' )
1681
-			),
1682
-			'actions'     => '',
1683
-			'test'        => 'ssl_support',
1684
-		);
1685
-
1686
-		$supports_https = wp_http_supports( array( 'ssl' ) );
1687
-
1688
-		if ( $supports_https ) {
1689
-			$result['status'] = 'good';
1690
-
1691
-			$result['label'] = __( 'Your site can communicate securely with other services' );
1692
-		} else {
1693
-			$result['status'] = 'critical';
1694
-
1695
-			$result['label'] = __( 'Your site is unable to communicate securely with other services' );
1696
-
1697
-			$result['description'] .= sprintf(
1698
-				'<p>%s</p>',
1699
-				__( 'Talk to your web host about OpenSSL support for PHP.' )
1700
-			);
1701
-		}
1702
-
1703
-		return $result;
1704
-	}
1705
-
1706
-	/**
1707
-	 * Test if scheduled events run as intended.
1708
-	 *
1709
-	 * If scheduled events are not running, this may indicate something with WP_Cron is not working
1710
-	 * as intended, or that there are orphaned events hanging around from older code.
1711
-	 *
1712
-	 * @since 5.2.0
1713
-	 *
1714
-	 * @return array The test results.
1715
-	 */
1716
-	public function get_test_scheduled_events() {
1717
-		$result = array(
1718
-			'label'       => __( 'Scheduled events are running' ),
1719
-			'status'      => 'good',
1720
-			'badge'       => array(
1721
-				'label' => __( 'Performance' ),
1722
-				'color' => 'blue',
1723
-			),
1724
-			'description' => sprintf(
1725
-				'<p>%s</p>',
1726
-				__( 'Scheduled events are what periodically looks for updates to plugins, themes and WordPress itself. It is also what makes sure scheduled posts are published on time. It may also be used by various plugins to make sure that planned actions are executed.' )
1727
-			),
1728
-			'actions'     => '',
1729
-			'test'        => 'scheduled_events',
1730
-		);
1731
-
1732
-		$this->wp_schedule_test_init();
1733
-
1734
-		if ( is_wp_error( $this->has_missed_cron() ) ) {
1735
-			$result['status'] = 'critical';
1736
-
1737
-			$result['label'] = __( 'It was not possible to check your scheduled events' );
1738
-
1739
-			$result['description'] = sprintf(
1740
-				'<p>%s</p>',
1741
-				sprintf(
1742
-					/* translators: %s: The error message returned while from the cron scheduler. */
1743
-					__( 'While trying to test your site&#8217;s scheduled events, the following error was returned: %s' ),
1744
-					$this->has_missed_cron()->get_error_message()
1745
-				)
1746
-			);
1747
-		} elseif ( $this->has_missed_cron() ) {
1748
-			$result['status'] = 'recommended';
1749
-
1750
-			$result['label'] = __( 'A scheduled event has failed' );
1751
-
1752
-			$result['description'] = sprintf(
1753
-				'<p>%s</p>',
1754
-				sprintf(
1755
-					/* translators: %s: The name of the failed cron event. */
1756
-					__( 'The scheduled event, %s, failed to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.' ),
1757
-					$this->last_missed_cron
1758
-				)
1759
-			);
1760
-		} elseif ( $this->has_late_cron() ) {
1761
-			$result['status'] = 'recommended';
1762
-
1763
-			$result['label'] = __( 'A scheduled event is late' );
1764
-
1765
-			$result['description'] = sprintf(
1766
-				'<p>%s</p>',
1767
-				sprintf(
1768
-					/* translators: %s: The name of the late cron event. */
1769
-					__( 'The scheduled event, %s, is late to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.' ),
1770
-					$this->last_late_cron
1771
-				)
1772
-			);
1773
-		}
1774
-
1775
-		return $result;
1776
-	}
1777
-
1778
-	/**
1779
-	 * Test if WordPress can run automated background updates.
1780
-	 *
1781
-	 * Background updates in WordPress are primarily used for minor releases and security updates.
1782
-	 * It's important to either have these working, or be aware that they are intentionally disabled
1783
-	 * for whatever reason.
1784
-	 *
1785
-	 * @since 5.2.0
1786
-	 *
1787
-	 * @return array The test results.
1788
-	 */
1789
-	public function get_test_background_updates() {
1790
-		$result = array(
1791
-			'label'       => __( 'Background updates are working' ),
1792
-			'status'      => 'good',
1793
-			'badge'       => array(
1794
-				'label' => __( 'Security' ),
1795
-				'color' => 'blue',
1796
-			),
1797
-			'description' => sprintf(
1798
-				'<p>%s</p>',
1799
-				__( 'Background updates ensure that WordPress can auto-update if a security update is released for the version you are currently using.' )
1800
-			),
1801
-			'actions'     => '',
1802
-			'test'        => 'background_updates',
1803
-		);
1804
-
1805
-		if ( ! class_exists( 'WP_Site_Health_Auto_Updates' ) ) {
1806
-			require_once ABSPATH . 'wp-admin/includes/class-wp-site-health-auto-updates.php';
1807
-		}
1808
-
1809
-		// Run the auto-update tests in a separate class,
1810
-		// as there are many considerations to be made.
1811
-		$automatic_updates = new WP_Site_Health_Auto_Updates();
1812
-		$tests             = $automatic_updates->run_tests();
1813
-
1814
-		$output = '<ul>';
1815
-
1816
-		foreach ( $tests as $test ) {
1817
-			$severity_string = __( 'Passed' );
1818
-
1819
-			if ( 'fail' === $test->severity ) {
1820
-				$result['label'] = __( 'Background updates are not working as expected' );
1821
-
1822
-				$result['status'] = 'critical';
1823
-
1824
-				$severity_string = __( 'Error' );
1825
-			}
1826
-
1827
-			if ( 'warning' === $test->severity && 'good' === $result['status'] ) {
1828
-				$result['label'] = __( 'Background updates may not be working properly' );
1829
-
1830
-				$result['status'] = 'recommended';
1831
-
1832
-				$severity_string = __( 'Warning' );
1833
-			}
1834
-
1835
-			$output .= sprintf(
1836
-				'<li><span class="dashicons %s"><span class="screen-reader-text">%s</span></span> %s</li>',
1837
-				esc_attr( $test->severity ),
1838
-				$severity_string,
1839
-				$test->description
1840
-			);
1841
-		}
1842
-
1843
-		$output .= '</ul>';
1844
-
1845
-		if ( 'good' !== $result['status'] ) {
1846
-			$result['description'] .= $output;
1847
-		}
1848
-
1849
-		return $result;
1850
-	}
1851
-
1852
-	/**
1853
-	 * Test if plugin and theme auto-updates appear to be configured correctly.
1854
-	 *
1855
-	 * @since 5.5.0
1856
-	 *
1857
-	 * @return array The test results.
1858
-	 */
1859
-	public function get_test_plugin_theme_auto_updates() {
1860
-		$result = array(
1861
-			'label'       => __( 'Plugin and theme auto-updates appear to be configured correctly' ),
1862
-			'status'      => 'good',
1863
-			'badge'       => array(
1864
-				'label' => __( 'Security' ),
1865
-				'color' => 'blue',
1866
-			),
1867
-			'description' => sprintf(
1868
-				'<p>%s</p>',
1869
-				__( 'Plugin and theme auto-updates ensure that the latest versions are always installed.' )
1870
-			),
1871
-			'actions'     => '',
1872
-			'test'        => 'plugin_theme_auto_updates',
1873
-		);
1874
-
1875
-		$check_plugin_theme_updates = $this->detect_plugin_theme_auto_update_issues();
1876
-
1877
-		$result['status'] = $check_plugin_theme_updates->status;
1878
-
1879
-		if ( 'good' !== $result['status'] ) {
1880
-			$result['label'] = __( 'Your site may have problems auto-updating plugins and themes' );
1881
-
1882
-			$result['description'] .= sprintf(
1883
-				'<p>%s</p>',
1884
-				$check_plugin_theme_updates->message
1885
-			);
1886
-		}
1887
-
1888
-		return $result;
1889
-	}
1890
-
1891
-	/**
1892
-	 * Test if loopbacks work as expected.
1893
-	 *
1894
-	 * A loopback is when WordPress queries itself, for example to start a new WP_Cron instance,
1895
-	 * or when editing a plugin or theme. This has shown itself to be a recurring issue,
1896
-	 * as code can very easily break this interaction.
1897
-	 *
1898
-	 * @since 5.2.0
1899
-	 *
1900
-	 * @return array The test results.
1901
-	 */
1902
-	public function get_test_loopback_requests() {
1903
-		$result = array(
1904
-			'label'       => __( 'Your site can perform loopback requests' ),
1905
-			'status'      => 'good',
1906
-			'badge'       => array(
1907
-				'label' => __( 'Performance' ),
1908
-				'color' => 'blue',
1909
-			),
1910
-			'description' => sprintf(
1911
-				'<p>%s</p>',
1912
-				__( 'Loopback requests are used to run scheduled events, and are also used by the built-in editors for themes and plugins to verify code stability.' )
1913
-			),
1914
-			'actions'     => '',
1915
-			'test'        => 'loopback_requests',
1916
-		);
1917
-
1918
-		$check_loopback = $this->can_perform_loopback();
1919
-
1920
-		$result['status'] = $check_loopback->status;
1921
-
1922
-		if ( 'good' !== $result['status'] ) {
1923
-			$result['label'] = __( 'Your site could not complete a loopback request' );
1924
-
1925
-			$result['description'] .= sprintf(
1926
-				'<p>%s</p>',
1927
-				$check_loopback->message
1928
-			);
1929
-		}
1930
-
1931
-		return $result;
1932
-	}
1933
-
1934
-	/**
1935
-	 * Test if HTTP requests are blocked.
1936
-	 *
1937
-	 * It's possible to block all outgoing communication (with the possibility of allowing certain
1938
-	 * hosts) via the HTTP API. This may create problems for users as many features are running as
1939
-	 * services these days.
1940
-	 *
1941
-	 * @since 5.2.0
1942
-	 *
1943
-	 * @return array The test results.
1944
-	 */
1945
-	public function get_test_http_requests() {
1946
-		$result = array(
1947
-			'label'       => __( 'HTTP requests seem to be working as expected' ),
1948
-			'status'      => 'good',
1949
-			'badge'       => array(
1950
-				'label' => __( 'Performance' ),
1951
-				'color' => 'blue',
1952
-			),
1953
-			'description' => sprintf(
1954
-				'<p>%s</p>',
1955
-				__( 'It is possible for site maintainers to block all, or some, communication to other sites and services. If set up incorrectly, this may prevent plugins and themes from working as intended.' )
1956
-			),
1957
-			'actions'     => '',
1958
-			'test'        => 'http_requests',
1959
-		);
1960
-
1961
-		$blocked = false;
1962
-		$hosts   = array();
1963
-
1964
-		if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
1965
-			$blocked = true;
1966
-		}
1967
-
1968
-		if ( defined( 'WP_ACCESSIBLE_HOSTS' ) ) {
1969
-			$hosts = explode( ',', WP_ACCESSIBLE_HOSTS );
1970
-		}
1971
-
1972
-		if ( $blocked && 0 === count( $hosts ) ) {
1973
-			$result['status'] = 'critical';
1974
-
1975
-			$result['label'] = __( 'HTTP requests are blocked' );
1976
-
1977
-			$result['description'] .= sprintf(
1978
-				'<p>%s</p>',
1979
-				sprintf(
1980
-					/* translators: %s: Name of the constant used. */
1981
-					__( 'HTTP requests have been blocked by the %s constant, with no allowed hosts.' ),
1982
-					'<code>WP_HTTP_BLOCK_EXTERNAL</code>'
1983
-				)
1984
-			);
1985
-		}
1986
-
1987
-		if ( $blocked && 0 < count( $hosts ) ) {
1988
-			$result['status'] = 'recommended';
1989
-
1990
-			$result['label'] = __( 'HTTP requests are partially blocked' );
1991
-
1992
-			$result['description'] .= sprintf(
1993
-				'<p>%s</p>',
1994
-				sprintf(
1995
-					/* translators: 1: Name of the constant used. 2: List of allowed hostnames. */
1996
-					__( 'HTTP requests have been blocked by the %1$s constant, with some allowed hosts: %2$s.' ),
1997
-					'<code>WP_HTTP_BLOCK_EXTERNAL</code>',
1998
-					implode( ',', $hosts )
1999
-				)
2000
-			);
2001
-		}
2002
-
2003
-		return $result;
2004
-	}
2005
-
2006
-	/**
2007
-	 * Test if the REST API is accessible.
2008
-	 *
2009
-	 * Various security measures may block the REST API from working, or it may have been disabled in general.
2010
-	 * This is required for the new block editor to work, so we explicitly test for this.
2011
-	 *
2012
-	 * @since 5.2.0
2013
-	 *
2014
-	 * @return array The test results.
2015
-	 */
2016
-	public function get_test_rest_availability() {
2017
-		$result = array(
2018
-			'label'       => __( 'The REST API is available' ),
2019
-			'status'      => 'good',
2020
-			'badge'       => array(
2021
-				'label' => __( 'Performance' ),
2022
-				'color' => 'blue',
2023
-			),
2024
-			'description' => sprintf(
2025
-				'<p>%s</p>',
2026
-				__( 'The REST API is one way WordPress, and other applications, communicate with the server. One example is the block editor screen, which relies on this to display, and save, your posts and pages.' )
2027
-			),
2028
-			'actions'     => '',
2029
-			'test'        => 'rest_availability',
2030
-		);
2031
-
2032
-		$cookies = wp_unslash( $_COOKIE );
2033
-		$timeout = 10;
2034
-		$headers = array(
2035
-			'Cache-Control' => 'no-cache',
2036
-			'X-WP-Nonce'    => wp_create_nonce( 'wp_rest' ),
2037
-		);
2038
-		/** This filter is documented in wp-includes/class-wp-http-streams.php */
2039
-		$sslverify = apply_filters( 'https_local_ssl_verify', false );
2040
-
2041
-		// Include Basic auth in loopback requests.
2042
-		if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
2043
-			$headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
2044
-		}
2045
-
2046
-		$url = rest_url( 'wp/v2/types/post' );
2047
-
2048
-		// The context for this is editing with the new block editor.
2049
-		$url = add_query_arg(
2050
-			array(
2051
-				'context' => 'edit',
2052
-			),
2053
-			$url
2054
-		);
2055
-
2056
-		$r = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout', 'sslverify' ) );
2057
-
2058
-		if ( is_wp_error( $r ) ) {
2059
-			$result['status'] = 'critical';
2060
-
2061
-			$result['label'] = __( 'The REST API encountered an error' );
2062
-
2063
-			$result['description'] .= sprintf(
2064
-				'<p>%s</p>',
2065
-				sprintf(
2066
-					'%s<br>%s',
2067
-					__( 'The REST API request failed due to an error.' ),
2068
-					sprintf(
2069
-						/* translators: 1: The WordPress error message. 2: The WordPress error code. */
2070
-						__( 'Error: %1$s (%2$s)' ),
2071
-						$r->get_error_message(),
2072
-						$r->get_error_code()
2073
-					)
2074
-				)
2075
-			);
2076
-		} elseif ( 200 !== wp_remote_retrieve_response_code( $r ) ) {
2077
-			$result['status'] = 'recommended';
2078
-
2079
-			$result['label'] = __( 'The REST API encountered an unexpected result' );
2080
-
2081
-			$result['description'] .= sprintf(
2082
-				'<p>%s</p>',
2083
-				sprintf(
2084
-					/* translators: 1: The HTTP error code. 2: The HTTP error message. */
2085
-					__( 'The REST API call gave the following unexpected result: (%1$d) %2$s.' ),
2086
-					wp_remote_retrieve_response_code( $r ),
2087
-					esc_html( wp_remote_retrieve_body( $r ) )
2088
-				)
2089
-			);
2090
-		} else {
2091
-			$json = json_decode( wp_remote_retrieve_body( $r ), true );
2092
-
2093
-			if ( false !== $json && ! isset( $json['capabilities'] ) ) {
2094
-				$result['status'] = 'recommended';
2095
-
2096
-				$result['label'] = __( 'The REST API did not behave correctly' );
2097
-
2098
-				$result['description'] .= sprintf(
2099
-					'<p>%s</p>',
2100
-					sprintf(
2101
-						/* translators: %s: The name of the query parameter being tested. */
2102
-						__( 'The REST API did not process the %s query parameter correctly.' ),
2103
-						'<code>context</code>'
2104
-					)
2105
-				);
2106
-			}
2107
-		}
2108
-
2109
-		return $result;
2110
-	}
2111
-
2112
-	/**
2113
-	 * Test if 'file_uploads' directive in PHP.ini is turned off.
2114
-	 *
2115
-	 * @since 5.5.0
2116
-	 *
2117
-	 * @return array The test results.
2118
-	 */
2119
-	public function get_test_file_uploads() {
2120
-		$result = array(
2121
-			'label'       => __( 'Files can be uploaded' ),
2122
-			'status'      => 'good',
2123
-			'badge'       => array(
2124
-				'label' => __( 'Performance' ),
2125
-				'color' => 'blue',
2126
-			),
2127
-			'description' => sprintf(
2128
-				'<p>%s</p>',
2129
-				sprintf(
2130
-					/* translators: 1: file_uploads, 2: php.ini */
2131
-					__( 'The %1$s directive in %2$s determines if uploading files is allowed on your site.' ),
2132
-					'<code>file_uploads</code>',
2133
-					'<code>php.ini</code>'
2134
-				)
2135
-			),
2136
-			'actions'     => '',
2137
-			'test'        => 'file_uploads',
2138
-		);
2139
-
2140
-		if ( ! function_exists( 'ini_get' ) ) {
2141
-			$result['status']       = 'critical';
2142
-			$result['description'] .= sprintf(
2143
-				/* translators: %s: ini_get() */
2144
-				__( 'The %s function has been disabled, some media settings are unavailable because of this.' ),
2145
-				'<code>ini_get()</code>'
2146
-			);
2147
-			return $result;
2148
-		}
2149
-
2150
-		if ( empty( ini_get( 'file_uploads' ) ) ) {
2151
-			$result['status']       = 'critical';
2152
-			$result['description'] .= sprintf(
2153
-				'<p>%s</p>',
2154
-				sprintf(
2155
-					/* translators: 1: file_uploads, 2: 0 */
2156
-					__( '%1$s is set to %2$s. You won\'t be able to upload files on your site.' ),
2157
-					'<code>file_uploads</code>',
2158
-					'<code>0</code>'
2159
-				)
2160
-			);
2161
-			return $result;
2162
-		}
2163
-
2164
-		$post_max_size       = ini_get( 'post_max_size' );
2165
-		$upload_max_filesize = ini_get( 'upload_max_filesize' );
2166
-
2167
-		if ( wp_convert_hr_to_bytes( $post_max_size ) < wp_convert_hr_to_bytes( $upload_max_filesize ) ) {
2168
-			$result['label'] = sprintf(
2169
-				/* translators: 1: post_max_size, 2: upload_max_filesize */
2170
-				__( 'The "%1$s" value is smaller than "%2$s"' ),
2171
-				'post_max_size',
2172
-				'upload_max_filesize'
2173
-			);
2174
-			$result['status'] = 'recommended';
2175
-
2176
-			if ( 0 === wp_convert_hr_to_bytes( $post_max_size ) ) {
2177
-				$result['description'] = sprintf(
2178
-					'<p>%s</p>',
2179
-					sprintf(
2180
-						/* translators: 1: post_max_size, 2: upload_max_filesize */
2181
-						__( 'The setting for %1$s is currently configured as 0, this could cause some problems when trying to upload files through plugin or theme features that rely on various upload methods. It is recommended to configure this setting to a fixed value, ideally matching the value of %2$s, as some upload methods read the value 0 as either unlimited, or disabled.' ),
2182
-						'<code>post_max_size</code>',
2183
-						'<code>upload_max_filesize</code>'
2184
-					)
2185
-				);
2186
-			} else {
2187
-				$result['description'] = sprintf(
2188
-					'<p>%s</p>',
2189
-					sprintf(
2190
-						/* translators: 1: post_max_size, 2: upload_max_filesize */
2191
-						__( 'The setting for %1$s is smaller than %2$s, this could cause some problems when trying to upload files.' ),
2192
-						'<code>post_max_size</code>',
2193
-						'<code>upload_max_filesize</code>'
2194
-					)
2195
-				);
2196
-			}
2197
-
2198
-			return $result;
2199
-		}
2200
-
2201
-		return $result;
2202
-	}
2203
-
2204
-	/**
2205
-	 * Tests if the Authorization header has the expected values.
2206
-	 *
2207
-	 * @since 5.6.0
2208
-	 *
2209
-	 * @return array
2210
-	 */
2211
-	public function get_test_authorization_header() {
2212
-		$result = array(
2213
-			'label'       => __( 'The Authorization header is working as expected' ),
2214
-			'status'      => 'good',
2215
-			'badge'       => array(
2216
-				'label' => __( 'Security' ),
2217
-				'color' => 'blue',
2218
-			),
2219
-			'description' => sprintf(
2220
-				'<p>%s</p>',
2221
-				__( 'The Authorization header comes from the third-party applications you approve. Without it, those apps cannot connect to your site.' )
2222
-			),
2223
-			'actions'     => '',
2224
-			'test'        => 'authorization_header',
2225
-		);
2226
-
2227
-		if ( ! isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) {
2228
-			$result['label'] = __( 'The authorization header is missing' );
2229
-		} elseif ( 'user' !== $_SERVER['PHP_AUTH_USER'] || 'pwd' !== $_SERVER['PHP_AUTH_PW'] ) {
2230
-			$result['label'] = __( 'The authorization header is invalid' );
2231
-		} else {
2232
-			return $result;
2233
-		}
2234
-
2235
-		$result['status'] = 'recommended';
2236
-
2237
-		if ( ! function_exists( 'got_mod_rewrite' ) ) {
2238
-			require_once ABSPATH . 'wp-admin/includes/misc.php';
2239
-		}
2240
-
2241
-		if ( got_mod_rewrite() ) {
2242
-			$result['actions'] .= sprintf(
2243
-				'<p><a href="%s">%s</a></p>',
2244
-				esc_url( admin_url( 'options-permalink.php' ) ),
2245
-				__( 'Flush permalinks' )
2246
-			);
2247
-		} else {
2248
-			$result['actions'] .= sprintf(
2249
-				'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
2250
-				__( 'https://developer.wordpress.org/rest-api/frequently-asked-questions/#why-is-authentication-not-working' ),
2251
-				__( 'Learn how to configure the Authorization header.' ),
2252
-				/* translators: Accessibility text. */
2253
-				__( '(opens in a new tab)' )
2254
-			);
2255
-		}
2256
-
2257
-		return $result;
2258
-	}
2259
-
2260
-	/**
2261
-	 * Return a set of tests that belong to the site status page.
2262
-	 *
2263
-	 * Each site status test is defined here, they may be `direct` tests, that run on page load, or `async` tests
2264
-	 * which will run later down the line via JavaScript calls to improve page performance and hopefully also user
2265
-	 * experiences.
2266
-	 *
2267
-	 * @since 5.2.0
2268
-	 * @since 5.6.0 Added support for `has_rest` and `permissions`.
2269
-	 *
2270
-	 * @return array The list of tests to run.
2271
-	 */
2272
-	public static function get_tests() {
2273
-		$tests = array(
2274
-			'direct' => array(
2275
-				'wordpress_version'         => array(
2276
-					'label' => __( 'WordPress Version' ),
2277
-					'test'  => 'wordpress_version',
2278
-				),
2279
-				'plugin_version'            => array(
2280
-					'label' => __( 'Plugin Versions' ),
2281
-					'test'  => 'plugin_version',
2282
-				),
2283
-				'theme_version'             => array(
2284
-					'label' => __( 'Theme Versions' ),
2285
-					'test'  => 'theme_version',
2286
-				),
2287
-				'php_version'               => array(
2288
-					'label' => __( 'PHP Version' ),
2289
-					'test'  => 'php_version',
2290
-				),
2291
-				'php_extensions'            => array(
2292
-					'label' => __( 'PHP Extensions' ),
2293
-					'test'  => 'php_extensions',
2294
-				),
2295
-				'php_default_timezone'      => array(
2296
-					'label' => __( 'PHP Default Timezone' ),
2297
-					'test'  => 'php_default_timezone',
2298
-				),
2299
-				'php_sessions'              => array(
2300
-					'label' => __( 'PHP Sessions' ),
2301
-					'test'  => 'php_sessions',
2302
-				),
2303
-				'sql_server'                => array(
2304
-					'label' => __( 'Database Server version' ),
2305
-					'test'  => 'sql_server',
2306
-				),
2307
-				'utf8mb4_support'           => array(
2308
-					'label' => __( 'MySQL utf8mb4 support' ),
2309
-					'test'  => 'utf8mb4_support',
2310
-				),
2311
-				'ssl_support'               => array(
2312
-					'label' => __( 'Secure communication' ),
2313
-					'test'  => 'ssl_support',
2314
-				),
2315
-				'scheduled_events'          => array(
2316
-					'label' => __( 'Scheduled events' ),
2317
-					'test'  => 'scheduled_events',
2318
-				),
2319
-				'http_requests'             => array(
2320
-					'label' => __( 'HTTP Requests' ),
2321
-					'test'  => 'http_requests',
2322
-				),
2323
-				'rest_availability'         => array(
2324
-					'label'     => __( 'REST API availability' ),
2325
-					'test'      => 'rest_availability',
2326
-					'skip_cron' => true,
2327
-				),
2328
-				'debug_enabled'             => array(
2329
-					'label' => __( 'Debugging enabled' ),
2330
-					'test'  => 'is_in_debug_mode',
2331
-				),
2332
-				'file_uploads'              => array(
2333
-					'label' => __( 'File uploads' ),
2334
-					'test'  => 'file_uploads',
2335
-				),
2336
-				'plugin_theme_auto_updates' => array(
2337
-					'label' => __( 'Plugin and theme auto-updates' ),
2338
-					'test'  => 'plugin_theme_auto_updates',
2339
-				),
2340
-			),
2341
-			'async'  => array(
2342
-				'dotorg_communication' => array(
2343
-					'label'             => __( 'Communication with WordPress.org' ),
2344
-					'test'              => rest_url( 'wp-site-health/v1/tests/dotorg-communication' ),
2345
-					'has_rest'          => true,
2346
-					'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_dotorg_communication' ),
2347
-				),
2348
-				'background_updates'   => array(
2349
-					'label'             => __( 'Background updates' ),
2350
-					'test'              => rest_url( 'wp-site-health/v1/tests/background-updates' ),
2351
-					'has_rest'          => true,
2352
-					'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_background_updates' ),
2353
-				),
2354
-				'loopback_requests'    => array(
2355
-					'label'             => __( 'Loopback request' ),
2356
-					'test'              => rest_url( 'wp-site-health/v1/tests/loopback-requests' ),
2357
-					'has_rest'          => true,
2358
-					'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_loopback_requests' ),
2359
-				),
2360
-				'https_status'         => array(
2361
-					'label'             => __( 'HTTPS status' ),
2362
-					'test'              => rest_url( 'wp-site-health/v1/tests/https-status' ),
2363
-					'has_rest'          => true,
2364
-					'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_https_status' ),
2365
-				),
2366
-			),
2367
-		);
2368
-
2369
-		// Conditionally include Authorization header test if the site isn't protected by Basic Auth.
2370
-		if ( ! wp_is_site_protected_by_basic_auth() ) {
2371
-			$tests['async']['authorization_header'] = array(
2372
-				'label'     => __( 'Authorization header' ),
2373
-				'test'      => rest_url( 'wp-site-health/v1/tests/authorization-header' ),
2374
-				'has_rest'  => true,
2375
-				'headers'   => array( 'Authorization' => 'Basic ' . base64_encode( 'user:pwd' ) ),
2376
-				'skip_cron' => true,
2377
-			);
2378
-		}
2379
-
2380
-		/**
2381
-		 * Add or modify which site status tests are run on a site.
2382
-		 *
2383
-		 * The site health is determined by a set of tests based on best practices from
2384
-		 * both the WordPress Hosting Team and web standards in general.
2385
-		 *
2386
-		 * Some sites may not have the same requirements, for example the automatic update
2387
-		 * checks may be handled by a host, and are therefore disabled in core.
2388
-		 * Or maybe you want to introduce a new test, is caching enabled/disabled/stale for example.
2389
-		 *
2390
-		 * Tests may be added either as direct, or asynchronous ones. Any test that may require some time
2391
-		 * to complete should run asynchronously, to avoid extended loading periods within wp-admin.
2392
-		 *
2393
-		 * @since 5.2.0
2394
-		 * @since 5.6.0 Added the `async_direct_test` array key for asynchronous tests.
2395
-		 *              Added the `skip_cron` array key for all tests.
2396
-		 *
2397
-		 * @param array[] $tests {
2398
-		 *     An associative array of direct and asynchronous tests.
2399
-		 *
2400
-		 *     @type array[] $direct {
2401
-		 *         An array of direct tests.
2402
-		 *
2403
-		 *         @type array ...$identifier {
2404
-		 *             `$identifier` should be a unique identifier for the test. Plugins and themes are encouraged to
2405
-		 *             prefix test identifiers with their slug to avoid collisions between tests.
2406
-		 *
2407
-		 *             @type string   $label     The friendly label to identify the test.
2408
-		 *             @type callable $test      The callback function that runs the test and returns its result.
2409
-		 *             @type bool     $skip_cron Whether to skip this test when running as cron.
2410
-		 *         }
2411
-		 *     }
2412
-		 *     @type array[] $async {
2413
-		 *         An array of asynchronous tests.
2414
-		 *
2415
-		 *         @type array ...$identifier {
2416
-		 *             `$identifier` should be a unique identifier for the test. Plugins and themes are encouraged to
2417
-		 *             prefix test identifiers with their slug to avoid collisions between tests.
2418
-		 *
2419
-		 *             @type string   $label             The friendly label to identify the test.
2420
-		 *             @type string   $test              An admin-ajax.php action to be called to perform the test, or
2421
-		 *                                               if `$has_rest` is true, a URL to a REST API endpoint to perform
2422
-		 *                                               the test.
2423
-		 *             @type bool     $has_rest          Whether the `$test` property points to a REST API endpoint.
2424
-		 *             @type bool     $skip_cron         Whether to skip this test when running as cron.
2425
-		 *             @type callable $async_direct_test A manner of directly calling the test marked as asynchronous,
2426
-		 *                                               as the scheduled event can not authenticate, and endpoints
2427
-		 *                                               may require authentication.
2428
-		 *         }
2429
-		 *     }
2430
-		 * }
2431
-		 */
2432
-		$tests = apply_filters( 'site_status_tests', $tests );
2433
-
2434
-		// Ensure that the filtered tests contain the required array keys.
2435
-		$tests = array_merge(
2436
-			array(
2437
-				'direct' => array(),
2438
-				'async'  => array(),
2439
-			),
2440
-			$tests
2441
-		);
2442
-
2443
-		return $tests;
2444
-	}
2445
-
2446
-	/**
2447
-	 * Add a class to the body HTML tag.
2448
-	 *
2449
-	 * Filters the body class string for admin pages and adds our own class for easier styling.
2450
-	 *
2451
-	 * @since 5.2.0
2452
-	 *
2453
-	 * @param string $body_class The body class string.
2454
-	 * @return string The modified body class string.
2455
-	 */
2456
-	public function admin_body_class( $body_class ) {
2457
-		$screen = get_current_screen();
2458
-		if ( 'site-health' !== $screen->id ) {
2459
-			return $body_class;
2460
-		}
2461
-
2462
-		$body_class .= ' site-health';
2463
-
2464
-		return $body_class;
2465
-	}
2466
-
2467
-	/**
2468
-	 * Initiate the WP_Cron schedule test cases.
2469
-	 *
2470
-	 * @since 5.2.0
2471
-	 */
2472
-	private function wp_schedule_test_init() {
2473
-		$this->schedules = wp_get_schedules();
2474
-		$this->get_cron_tasks();
2475
-	}
2476
-
2477
-	/**
2478
-	 * Populate our list of cron events and store them to a class-wide variable.
2479
-	 *
2480
-	 * @since 5.2.0
2481
-	 */
2482
-	private function get_cron_tasks() {
2483
-		$cron_tasks = _get_cron_array();
2484
-
2485
-		if ( empty( $cron_tasks ) ) {
2486
-			$this->crons = new WP_Error( 'no_tasks', __( 'No scheduled events exist on this site.' ) );
2487
-			return;
2488
-		}
2489
-
2490
-		$this->crons = array();
2491
-
2492
-		foreach ( $cron_tasks as $time => $cron ) {
2493
-			foreach ( $cron as $hook => $dings ) {
2494
-				foreach ( $dings as $sig => $data ) {
2495
-
2496
-					$this->crons[ "$hook-$sig-$time" ] = (object) array(
2497
-						'hook'     => $hook,
2498
-						'time'     => $time,
2499
-						'sig'      => $sig,
2500
-						'args'     => $data['args'],
2501
-						'schedule' => $data['schedule'],
2502
-						'interval' => isset( $data['interval'] ) ? $data['interval'] : null,
2503
-					);
2504
-
2505
-				}
2506
-			}
2507
-		}
2508
-	}
2509
-
2510
-	/**
2511
-	 * Check if any scheduled tasks have been missed.
2512
-	 *
2513
-	 * Returns a boolean value of `true` if a scheduled task has been missed and ends processing.
2514
-	 *
2515
-	 * If the list of crons is an instance of WP_Error, returns the instance instead of a boolean value.
2516
-	 *
2517
-	 * @since 5.2.0
2518
-	 *
2519
-	 * @return bool|WP_Error True if a cron was missed, false if not. WP_Error if the cron is set to that.
2520
-	 */
2521
-	public function has_missed_cron() {
2522
-		if ( is_wp_error( $this->crons ) ) {
2523
-			return $this->crons;
2524
-		}
2525
-
2526
-		foreach ( $this->crons as $id => $cron ) {
2527
-			if ( ( $cron->time - time() ) < $this->timeout_missed_cron ) {
2528
-				$this->last_missed_cron = $cron->hook;
2529
-				return true;
2530
-			}
2531
-		}
2532
-
2533
-		return false;
2534
-	}
2535
-
2536
-	/**
2537
-	 * Check if any scheduled tasks are late.
2538
-	 *
2539
-	 * Returns a boolean value of `true` if a scheduled task is late and ends processing.
2540
-	 *
2541
-	 * If the list of crons is an instance of WP_Error, returns the instance instead of a boolean value.
2542
-	 *
2543
-	 * @since 5.3.0
2544
-	 *
2545
-	 * @return bool|WP_Error True if a cron is late, false if not. WP_Error if the cron is set to that.
2546
-	 */
2547
-	public function has_late_cron() {
2548
-		if ( is_wp_error( $this->crons ) ) {
2549
-			return $this->crons;
2550
-		}
2551
-
2552
-		foreach ( $this->crons as $id => $cron ) {
2553
-			$cron_offset = $cron->time - time();
2554
-			if (
2555
-				$cron_offset >= $this->timeout_missed_cron &&
2556
-				$cron_offset < $this->timeout_late_cron
2557
-			) {
2558
-				$this->last_late_cron = $cron->hook;
2559
-				return true;
2560
-			}
2561
-		}
2562
-
2563
-		return false;
2564
-	}
2565
-
2566
-	/**
2567
-	 * Check for potential issues with plugin and theme auto-updates.
2568
-	 *
2569
-	 * Though there is no way to 100% determine if plugin and theme auto-updates are configured
2570
-	 * correctly, a few educated guesses could be made to flag any conditions that would
2571
-	 * potentially cause unexpected behaviors.
2572
-	 *
2573
-	 * @since 5.5.0
2574
-	 *
2575
-	 * @return object The test results.
2576
-	 */
2577
-	public function detect_plugin_theme_auto_update_issues() {
2578
-		$mock_plugin = (object) array(
2579
-			'id'            => 'w.org/plugins/a-fake-plugin',
2580
-			'slug'          => 'a-fake-plugin',
2581
-			'plugin'        => 'a-fake-plugin/a-fake-plugin.php',
2582
-			'new_version'   => '9.9',
2583
-			'url'           => 'https://wordpress.org/plugins/a-fake-plugin/',
2584
-			'package'       => 'https://downloads.wordpress.org/plugin/a-fake-plugin.9.9.zip',
2585
-			'icons'         => array(
2586
-				'2x' => 'https://ps.w.org/a-fake-plugin/assets/icon-256x256.png',
2587
-				'1x' => 'https://ps.w.org/a-fake-plugin/assets/icon-128x128.png',
2588
-			),
2589
-			'banners'       => array(
2590
-				'2x' => 'https://ps.w.org/a-fake-plugin/assets/banner-1544x500.png',
2591
-				'1x' => 'https://ps.w.org/a-fake-plugin/assets/banner-772x250.png',
2592
-			),
2593
-			'banners_rtl'   => array(),
2594
-			'tested'        => '5.5.0',
2595
-			'requires_php'  => '5.6.20',
2596
-			'compatibility' => new stdClass(),
2597
-		);
2598
-
2599
-		$mock_theme = (object) array(
2600
-			'theme'        => 'a-fake-theme',
2601
-			'new_version'  => '9.9',
2602
-			'url'          => 'https://wordpress.org/themes/a-fake-theme/',
2603
-			'package'      => 'https://downloads.wordpress.org/theme/a-fake-theme.9.9.zip',
2604
-			'requires'     => '5.0.0',
2605
-			'requires_php' => '5.6.20',
2606
-		);
2607
-
2608
-		$test_plugins_enabled = wp_is_auto_update_forced_for_item( 'plugin', true, $mock_plugin );
2609
-		$test_themes_enabled  = wp_is_auto_update_forced_for_item( 'theme', true, $mock_theme );
2610
-
2611
-		$ui_enabled_for_plugins = wp_is_auto_update_enabled_for_type( 'plugin' );
2612
-		$ui_enabled_for_themes  = wp_is_auto_update_enabled_for_type( 'theme' );
2613
-		$plugin_filter_present  = has_filter( 'auto_update_plugin' );
2614
-		$theme_filter_present   = has_filter( 'auto_update_theme' );
2615
-
2616
-		if ( ( ! $test_plugins_enabled && $ui_enabled_for_plugins )
2617
-			|| ( ! $test_themes_enabled && $ui_enabled_for_themes )
2618
-		) {
2619
-			return (object) array(
2620
-				'status'  => 'critical',
2621
-				'message' => __( 'Auto-updates for plugins and/or themes appear to be disabled, but settings are still set to be displayed. This could cause auto-updates to not work as expected.' ),
2622
-			);
2623
-		}
2624
-
2625
-		if ( ( ! $test_plugins_enabled && $plugin_filter_present )
2626
-			&& ( ! $test_themes_enabled && $theme_filter_present )
2627
-		) {
2628
-			return (object) array(
2629
-				'status'  => 'recommended',
2630
-				'message' => __( 'Auto-updates for plugins and themes appear to be disabled. This will prevent your site from receiving new versions automatically when available.' ),
2631
-			);
2632
-		} elseif ( ! $test_plugins_enabled && $plugin_filter_present ) {
2633
-			return (object) array(
2634
-				'status'  => 'recommended',
2635
-				'message' => __( 'Auto-updates for plugins appear to be disabled. This will prevent your site from receiving new versions automatically when available.' ),
2636
-			);
2637
-		} elseif ( ! $test_themes_enabled && $theme_filter_present ) {
2638
-			return (object) array(
2639
-				'status'  => 'recommended',
2640
-				'message' => __( 'Auto-updates for themes appear to be disabled. This will prevent your site from receiving new versions automatically when available.' ),
2641
-			);
2642
-		}
2643
-
2644
-		return (object) array(
2645
-			'status'  => 'good',
2646
-			'message' => __( 'There appear to be no issues with plugin and theme auto-updates.' ),
2647
-		);
2648
-	}
2649
-
2650
-	/**
2651
-	 * Run a loopback test on our site.
2652
-	 *
2653
-	 * Loopbacks are what WordPress uses to communicate with itself to start up WP_Cron, scheduled posts,
2654
-	 * make sure plugin or theme edits don't cause site failures and similar.
2655
-	 *
2656
-	 * @since 5.2.0
2657
-	 *
2658
-	 * @return object The test results.
2659
-	 */
2660
-	public function can_perform_loopback() {
2661
-		$body    = array( 'site-health' => 'loopback-test' );
2662
-		$cookies = wp_unslash( $_COOKIE );
2663
-		$timeout = 10;
2664
-		$headers = array(
2665
-			'Cache-Control' => 'no-cache',
2666
-		);
2667
-		/** This filter is documented in wp-includes/class-wp-http-streams.php */
2668
-		$sslverify = apply_filters( 'https_local_ssl_verify', false );
2669
-
2670
-		// Include Basic auth in loopback requests.
2671
-		if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
2672
-			$headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
2673
-		}
2674
-
2675
-		$url = site_url( 'wp-cron.php' );
2676
-
2677
-		/*
1336
+        if ( false !== strpos( $mysql_client_version, 'mysqlnd' ) ) {
1337
+            $mysql_client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $mysql_client_version );
1338
+            if ( version_compare( $mysql_client_version, '5.0.9', '<' ) ) {
1339
+                $result['status'] = 'recommended';
1340
+
1341
+                $result['label'] = __( 'utf8mb4 requires a newer client library' );
1342
+
1343
+                $result['description'] .= sprintf(
1344
+                    '<p>%s</p>',
1345
+                    sprintf(
1346
+                        /* translators: 1: Name of the library, 2: Number of version. */
1347
+                        __( 'WordPress&#8217; utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer. Please contact your server administrator.' ),
1348
+                        'mysqlnd',
1349
+                        '5.0.9'
1350
+                    )
1351
+                );
1352
+            }
1353
+        } else {
1354
+            if ( version_compare( $mysql_client_version, '5.5.3', '<' ) ) {
1355
+                $result['status'] = 'recommended';
1356
+
1357
+                $result['label'] = __( 'utf8mb4 requires a newer client library' );
1358
+
1359
+                $result['description'] .= sprintf(
1360
+                    '<p>%s</p>',
1361
+                    sprintf(
1362
+                        /* translators: 1: Name of the library, 2: Number of version. */
1363
+                        __( 'WordPress&#8217; utf8mb4 support requires MySQL client library (%1$s) version %2$s or newer. Please contact your server administrator.' ),
1364
+                        'libmysql',
1365
+                        '5.5.3'
1366
+                    )
1367
+                );
1368
+            }
1369
+        }
1370
+
1371
+        return $result;
1372
+    }
1373
+
1374
+    /**
1375
+     * Test if the site can communicate with WordPress.org.
1376
+     *
1377
+     * @since 5.2.0
1378
+     *
1379
+     * @return array The test results.
1380
+     */
1381
+    public function get_test_dotorg_communication() {
1382
+        $result = array(
1383
+            'label'       => __( 'Can communicate with WordPress.org' ),
1384
+            'status'      => '',
1385
+            'badge'       => array(
1386
+                'label' => __( 'Security' ),
1387
+                'color' => 'blue',
1388
+            ),
1389
+            'description' => sprintf(
1390
+                '<p>%s</p>',
1391
+                __( 'Communicating with the WordPress servers is used to check for new versions, and to both install and update WordPress core, themes or plugins.' )
1392
+            ),
1393
+            'actions'     => '',
1394
+            'test'        => 'dotorg_communication',
1395
+        );
1396
+
1397
+        $wp_dotorg = wp_remote_get(
1398
+            'https://api.wordpress.org',
1399
+            array(
1400
+                'timeout' => 10,
1401
+            )
1402
+        );
1403
+        if ( ! is_wp_error( $wp_dotorg ) ) {
1404
+            $result['status'] = 'good';
1405
+        } else {
1406
+            $result['status'] = 'critical';
1407
+
1408
+            $result['label'] = __( 'Could not reach WordPress.org' );
1409
+
1410
+            $result['description'] .= sprintf(
1411
+                '<p>%s</p>',
1412
+                sprintf(
1413
+                    '<span class="error"><span class="screen-reader-text">%s</span></span> %s',
1414
+                    __( 'Error' ),
1415
+                    sprintf(
1416
+                        /* translators: 1: The IP address WordPress.org resolves to. 2: The error returned by the lookup. */
1417
+                        __( 'Your site is unable to reach WordPress.org at %1$s, and returned the error: %2$s' ),
1418
+                        gethostbyname( 'api.wordpress.org' ),
1419
+                        $wp_dotorg->get_error_message()
1420
+                    )
1421
+                )
1422
+            );
1423
+
1424
+            $result['actions'] = sprintf(
1425
+                '<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1426
+                /* translators: Localized Support reference. */
1427
+                esc_url( __( 'https://wordpress.org/support' ) ),
1428
+                __( 'Get help resolving this issue.' ),
1429
+                /* translators: Accessibility text. */
1430
+                __( '(opens in a new tab)' )
1431
+            );
1432
+        }
1433
+
1434
+        return $result;
1435
+    }
1436
+
1437
+    /**
1438
+     * Test if debug information is enabled.
1439
+     *
1440
+     * When WP_DEBUG is enabled, errors and information may be disclosed to site visitors,
1441
+     * or logged to a publicly accessible file.
1442
+     *
1443
+     * Debugging is also frequently left enabled after looking for errors on a site,
1444
+     * as site owners do not understand the implications of this.
1445
+     *
1446
+     * @since 5.2.0
1447
+     *
1448
+     * @return array The test results.
1449
+     */
1450
+    public function get_test_is_in_debug_mode() {
1451
+        $result = array(
1452
+            'label'       => __( 'Your site is not set to output debug information' ),
1453
+            'status'      => 'good',
1454
+            'badge'       => array(
1455
+                'label' => __( 'Security' ),
1456
+                'color' => 'blue',
1457
+            ),
1458
+            'description' => sprintf(
1459
+                '<p>%s</p>',
1460
+                __( 'Debug mode is often enabled to gather more details about an error or site failure, but may contain sensitive information which should not be available on a publicly available website.' )
1461
+            ),
1462
+            'actions'     => sprintf(
1463
+                '<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1464
+                /* translators: Documentation explaining debugging in WordPress. */
1465
+                esc_url( __( 'https://wordpress.org/support/article/debugging-in-wordpress/' ) ),
1466
+                __( 'Learn more about debugging in WordPress.' ),
1467
+                /* translators: Accessibility text. */
1468
+                __( '(opens in a new tab)' )
1469
+            ),
1470
+            'test'        => 'is_in_debug_mode',
1471
+        );
1472
+
1473
+        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
1474
+            if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
1475
+                $result['label'] = __( 'Your site is set to log errors to a potentially public file' );
1476
+
1477
+                $result['status'] = ( 0 === strpos( ini_get( 'error_log' ), ABSPATH ) ) ? 'critical' : 'recommended';
1478
+
1479
+                $result['description'] .= sprintf(
1480
+                    '<p>%s</p>',
1481
+                    sprintf(
1482
+                        /* translators: %s: WP_DEBUG_LOG */
1483
+                        __( 'The value, %s, has been added to this website&#8217;s configuration file. This means any errors on the site will be written to a file which is potentially available to all users.' ),
1484
+                        '<code>WP_DEBUG_LOG</code>'
1485
+                    )
1486
+                );
1487
+            }
1488
+
1489
+            if ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) {
1490
+                $result['label'] = __( 'Your site is set to display errors to site visitors' );
1491
+
1492
+                $result['status'] = 'critical';
1493
+
1494
+                // On development environments, set the status to recommended.
1495
+                if ( $this->is_development_environment() ) {
1496
+                    $result['status'] = 'recommended';
1497
+                }
1498
+
1499
+                $result['description'] .= sprintf(
1500
+                    '<p>%s</p>',
1501
+                    sprintf(
1502
+                        /* translators: 1: WP_DEBUG_DISPLAY, 2: WP_DEBUG */
1503
+                        __( 'The value, %1$s, has either been enabled by %2$s or added to your configuration file. This will make errors display on the front end of your site.' ),
1504
+                        '<code>WP_DEBUG_DISPLAY</code>',
1505
+                        '<code>WP_DEBUG</code>'
1506
+                    )
1507
+                );
1508
+            }
1509
+        }
1510
+
1511
+        return $result;
1512
+    }
1513
+
1514
+    /**
1515
+     * Test if your site is serving content over HTTPS.
1516
+     *
1517
+     * Many sites have varying degrees of HTTPS support, the most common of which is sites that have it
1518
+     * enabled, but only if you visit the right site address.
1519
+     *
1520
+     * @since 5.2.0
1521
+     * @since 5.7.0 Updated to rely on {@see wp_is_using_https()} and {@see wp_is_https_supported()}.
1522
+     *
1523
+     * @return array The test results.
1524
+     */
1525
+    public function get_test_https_status() {
1526
+        // Enforce fresh HTTPS detection results. This is normally invoked by using cron,
1527
+        // but for Site Health it should always rely on the latest results.
1528
+        wp_update_https_detection_errors();
1529
+
1530
+        $default_update_url = wp_get_default_update_https_url();
1531
+
1532
+        $result = array(
1533
+            'label'       => __( 'Your website is using an active HTTPS connection' ),
1534
+            'status'      => 'good',
1535
+            'badge'       => array(
1536
+                'label' => __( 'Security' ),
1537
+                'color' => 'blue',
1538
+            ),
1539
+            'description' => sprintf(
1540
+                '<p>%s</p>',
1541
+                __( 'An HTTPS connection is a more secure way of browsing the web. Many services now have HTTPS as a requirement. HTTPS allows you to take advantage of new features that can increase site speed, improve search rankings, and gain the trust of your visitors by helping to protect their online privacy.' )
1542
+            ),
1543
+            'actions'     => sprintf(
1544
+                '<p><a href="%s" target="_blank" rel="noopener">%s<span class="screen-reader-text"> %s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1545
+                esc_url( $default_update_url ),
1546
+                __( 'Learn more about why you should use HTTPS' ),
1547
+                /* translators: Accessibility text. */
1548
+                __( '(opens in a new tab)' )
1549
+            ),
1550
+            'test'        => 'https_status',
1551
+        );
1552
+
1553
+        if ( ! wp_is_using_https() ) {
1554
+            // If the website is not using HTTPS, provide more information
1555
+            // about whether it is supported and how it can be enabled.
1556
+            $result['status'] = 'recommended';
1557
+            $result['label']  = __( 'Your website does not use HTTPS' );
1558
+
1559
+            if ( wp_is_site_url_using_https() ) {
1560
+                if ( is_ssl() ) {
1561
+                    $result['description'] = sprintf(
1562
+                        '<p>%s</p>',
1563
+                        sprintf(
1564
+                            /* translators: %s: URL to Settings > General > Site Address. */
1565
+                            __( 'You are accessing this website using HTTPS, but your <a href="%s">Site Address</a> is not set up to use HTTPS by default.' ),
1566
+                            esc_url( admin_url( 'options-general.php' ) . '#home' )
1567
+                        )
1568
+                    );
1569
+                } else {
1570
+                    $result['description'] = sprintf(
1571
+                        '<p>%s</p>',
1572
+                        sprintf(
1573
+                            /* translators: %s: URL to Settings > General > Site Address. */
1574
+                            __( 'Your <a href="%s">Site Address</a> is not set up to use HTTPS.' ),
1575
+                            esc_url( admin_url( 'options-general.php' ) . '#home' )
1576
+                        )
1577
+                    );
1578
+                }
1579
+            } else {
1580
+                if ( is_ssl() ) {
1581
+                    $result['description'] = sprintf(
1582
+                        '<p>%s</p>',
1583
+                        sprintf(
1584
+                            /* translators: 1: URL to Settings > General > WordPress Address, 2: URL to Settings > General > Site Address. */
1585
+                            __( 'You are accessing this website using HTTPS, but your <a href="%1$s">WordPress Address</a> and <a href="%2$s">Site Address</a> are not set up to use HTTPS by default.' ),
1586
+                            esc_url( admin_url( 'options-general.php' ) . '#siteurl' ),
1587
+                            esc_url( admin_url( 'options-general.php' ) . '#home' )
1588
+                        )
1589
+                    );
1590
+                } else {
1591
+                    $result['description'] = sprintf(
1592
+                        '<p>%s</p>',
1593
+                        sprintf(
1594
+                            /* translators: 1: URL to Settings > General > WordPress Address, 2: URL to Settings > General > Site Address. */
1595
+                            __( 'Your <a href="%1$s">WordPress Address</a> and <a href="%2$s">Site Address</a> are not set up to use HTTPS.' ),
1596
+                            esc_url( admin_url( 'options-general.php' ) . '#siteurl' ),
1597
+                            esc_url( admin_url( 'options-general.php' ) . '#home' )
1598
+                        )
1599
+                    );
1600
+                }
1601
+            }
1602
+
1603
+            if ( wp_is_https_supported() ) {
1604
+                $result['description'] .= sprintf(
1605
+                    '<p>%s</p>',
1606
+                    __( 'HTTPS is already supported for your website.' )
1607
+                );
1608
+
1609
+                if ( defined( 'WP_HOME' ) || defined( 'WP_SITEURL' ) ) {
1610
+                    $result['description'] .= sprintf(
1611
+                        '<p>%s</p>',
1612
+                        sprintf(
1613
+                            /* translators: 1: wp-config.php, 2: WP_HOME, 3: WP_SITEURL */
1614
+                            __( 'However, your WordPress Address is currently controlled by a PHP constant and therefore cannot be updated. You need to edit your %1$s and remove or update the definitions of %2$s and %3$s.' ),
1615
+                            '<code>wp-config.php</code>',
1616
+                            '<code>WP_HOME</code>',
1617
+                            '<code>WP_SITEURL</code>'
1618
+                        )
1619
+                    );
1620
+                } elseif ( current_user_can( 'update_https' ) ) {
1621
+                    $default_direct_update_url = add_query_arg( 'action', 'update_https', wp_nonce_url( admin_url( 'site-health.php' ), 'wp_update_https' ) );
1622
+                    $direct_update_url         = wp_get_direct_update_https_url();
1623
+
1624
+                    if ( ! empty( $direct_update_url ) ) {
1625
+                        $result['actions'] = sprintf(
1626
+                            '<p class="button-container"><a class="button button-primary" href="%1$s" target="_blank" rel="noopener">%2$s<span class="screen-reader-text"> %3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1627
+                            esc_url( $direct_update_url ),
1628
+                            __( 'Update your site to use HTTPS' ),
1629
+                            /* translators: Accessibility text. */
1630
+                            __( '(opens in a new tab)' )
1631
+                        );
1632
+                    } else {
1633
+                        $result['actions'] = sprintf(
1634
+                            '<p class="button-container"><a class="button button-primary" href="%1$s">%2$s</a></p>',
1635
+                            esc_url( $default_direct_update_url ),
1636
+                            __( 'Update your site to use HTTPS' )
1637
+                        );
1638
+                    }
1639
+                }
1640
+            } else {
1641
+                // If host-specific "Update HTTPS" URL is provided, include a link.
1642
+                $update_url = wp_get_update_https_url();
1643
+                if ( $update_url !== $default_update_url ) {
1644
+                    $result['description'] .= sprintf(
1645
+                        '<p><a href="%s" target="_blank" rel="noopener">%s<span class="screen-reader-text"> %s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
1646
+                        esc_url( $update_url ),
1647
+                        __( 'Talk to your web host about supporting HTTPS for your website.' ),
1648
+                        /* translators: Accessibility text. */
1649
+                        __( '(opens in a new tab)' )
1650
+                    );
1651
+                } else {
1652
+                    $result['description'] .= sprintf(
1653
+                        '<p>%s</p>',
1654
+                        __( 'Talk to your web host about supporting HTTPS for your website.' )
1655
+                    );
1656
+                }
1657
+            }
1658
+        }
1659
+
1660
+        return $result;
1661
+    }
1662
+
1663
+    /**
1664
+     * Check if the HTTP API can handle SSL/TLS requests.
1665
+     *
1666
+     * @since 5.2.0
1667
+     *
1668
+     * @return array The test results.
1669
+     */
1670
+    public function get_test_ssl_support() {
1671
+        $result = array(
1672
+            'label'       => '',
1673
+            'status'      => '',
1674
+            'badge'       => array(
1675
+                'label' => __( 'Security' ),
1676
+                'color' => 'blue',
1677
+            ),
1678
+            'description' => sprintf(
1679
+                '<p>%s</p>',
1680
+                __( 'Securely communicating between servers are needed for transactions such as fetching files, conducting sales on store sites, and much more.' )
1681
+            ),
1682
+            'actions'     => '',
1683
+            'test'        => 'ssl_support',
1684
+        );
1685
+
1686
+        $supports_https = wp_http_supports( array( 'ssl' ) );
1687
+
1688
+        if ( $supports_https ) {
1689
+            $result['status'] = 'good';
1690
+
1691
+            $result['label'] = __( 'Your site can communicate securely with other services' );
1692
+        } else {
1693
+            $result['status'] = 'critical';
1694
+
1695
+            $result['label'] = __( 'Your site is unable to communicate securely with other services' );
1696
+
1697
+            $result['description'] .= sprintf(
1698
+                '<p>%s</p>',
1699
+                __( 'Talk to your web host about OpenSSL support for PHP.' )
1700
+            );
1701
+        }
1702
+
1703
+        return $result;
1704
+    }
1705
+
1706
+    /**
1707
+     * Test if scheduled events run as intended.
1708
+     *
1709
+     * If scheduled events are not running, this may indicate something with WP_Cron is not working
1710
+     * as intended, or that there are orphaned events hanging around from older code.
1711
+     *
1712
+     * @since 5.2.0
1713
+     *
1714
+     * @return array The test results.
1715
+     */
1716
+    public function get_test_scheduled_events() {
1717
+        $result = array(
1718
+            'label'       => __( 'Scheduled events are running' ),
1719
+            'status'      => 'good',
1720
+            'badge'       => array(
1721
+                'label' => __( 'Performance' ),
1722
+                'color' => 'blue',
1723
+            ),
1724
+            'description' => sprintf(
1725
+                '<p>%s</p>',
1726
+                __( 'Scheduled events are what periodically looks for updates to plugins, themes and WordPress itself. It is also what makes sure scheduled posts are published on time. It may also be used by various plugins to make sure that planned actions are executed.' )
1727
+            ),
1728
+            'actions'     => '',
1729
+            'test'        => 'scheduled_events',
1730
+        );
1731
+
1732
+        $this->wp_schedule_test_init();
1733
+
1734
+        if ( is_wp_error( $this->has_missed_cron() ) ) {
1735
+            $result['status'] = 'critical';
1736
+
1737
+            $result['label'] = __( 'It was not possible to check your scheduled events' );
1738
+
1739
+            $result['description'] = sprintf(
1740
+                '<p>%s</p>',
1741
+                sprintf(
1742
+                    /* translators: %s: The error message returned while from the cron scheduler. */
1743
+                    __( 'While trying to test your site&#8217;s scheduled events, the following error was returned: %s' ),
1744
+                    $this->has_missed_cron()->get_error_message()
1745
+                )
1746
+            );
1747
+        } elseif ( $this->has_missed_cron() ) {
1748
+            $result['status'] = 'recommended';
1749
+
1750
+            $result['label'] = __( 'A scheduled event has failed' );
1751
+
1752
+            $result['description'] = sprintf(
1753
+                '<p>%s</p>',
1754
+                sprintf(
1755
+                    /* translators: %s: The name of the failed cron event. */
1756
+                    __( 'The scheduled event, %s, failed to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.' ),
1757
+                    $this->last_missed_cron
1758
+                )
1759
+            );
1760
+        } elseif ( $this->has_late_cron() ) {
1761
+            $result['status'] = 'recommended';
1762
+
1763
+            $result['label'] = __( 'A scheduled event is late' );
1764
+
1765
+            $result['description'] = sprintf(
1766
+                '<p>%s</p>',
1767
+                sprintf(
1768
+                    /* translators: %s: The name of the late cron event. */
1769
+                    __( 'The scheduled event, %s, is late to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.' ),
1770
+                    $this->last_late_cron
1771
+                )
1772
+            );
1773
+        }
1774
+
1775
+        return $result;
1776
+    }
1777
+
1778
+    /**
1779
+     * Test if WordPress can run automated background updates.
1780
+     *
1781
+     * Background updates in WordPress are primarily used for minor releases and security updates.
1782
+     * It's important to either have these working, or be aware that they are intentionally disabled
1783
+     * for whatever reason.
1784
+     *
1785
+     * @since 5.2.0
1786
+     *
1787
+     * @return array The test results.
1788
+     */
1789
+    public function get_test_background_updates() {
1790
+        $result = array(
1791
+            'label'       => __( 'Background updates are working' ),
1792
+            'status'      => 'good',
1793
+            'badge'       => array(
1794
+                'label' => __( 'Security' ),
1795
+                'color' => 'blue',
1796
+            ),
1797
+            'description' => sprintf(
1798
+                '<p>%s</p>',
1799
+                __( 'Background updates ensure that WordPress can auto-update if a security update is released for the version you are currently using.' )
1800
+            ),
1801
+            'actions'     => '',
1802
+            'test'        => 'background_updates',
1803
+        );
1804
+
1805
+        if ( ! class_exists( 'WP_Site_Health_Auto_Updates' ) ) {
1806
+            require_once ABSPATH . 'wp-admin/includes/class-wp-site-health-auto-updates.php';
1807
+        }
1808
+
1809
+        // Run the auto-update tests in a separate class,
1810
+        // as there are many considerations to be made.
1811
+        $automatic_updates = new WP_Site_Health_Auto_Updates();
1812
+        $tests             = $automatic_updates->run_tests();
1813
+
1814
+        $output = '<ul>';
1815
+
1816
+        foreach ( $tests as $test ) {
1817
+            $severity_string = __( 'Passed' );
1818
+
1819
+            if ( 'fail' === $test->severity ) {
1820
+                $result['label'] = __( 'Background updates are not working as expected' );
1821
+
1822
+                $result['status'] = 'critical';
1823
+
1824
+                $severity_string = __( 'Error' );
1825
+            }
1826
+
1827
+            if ( 'warning' === $test->severity && 'good' === $result['status'] ) {
1828
+                $result['label'] = __( 'Background updates may not be working properly' );
1829
+
1830
+                $result['status'] = 'recommended';
1831
+
1832
+                $severity_string = __( 'Warning' );
1833
+            }
1834
+
1835
+            $output .= sprintf(
1836
+                '<li><span class="dashicons %s"><span class="screen-reader-text">%s</span></span> %s</li>',
1837
+                esc_attr( $test->severity ),
1838
+                $severity_string,
1839
+                $test->description
1840
+            );
1841
+        }
1842
+
1843
+        $output .= '</ul>';
1844
+
1845
+        if ( 'good' !== $result['status'] ) {
1846
+            $result['description'] .= $output;
1847
+        }
1848
+
1849
+        return $result;
1850
+    }
1851
+
1852
+    /**
1853
+     * Test if plugin and theme auto-updates appear to be configured correctly.
1854
+     *
1855
+     * @since 5.5.0
1856
+     *
1857
+     * @return array The test results.
1858
+     */
1859
+    public function get_test_plugin_theme_auto_updates() {
1860
+        $result = array(
1861
+            'label'       => __( 'Plugin and theme auto-updates appear to be configured correctly' ),
1862
+            'status'      => 'good',
1863
+            'badge'       => array(
1864
+                'label' => __( 'Security' ),
1865
+                'color' => 'blue',
1866
+            ),
1867
+            'description' => sprintf(
1868
+                '<p>%s</p>',
1869
+                __( 'Plugin and theme auto-updates ensure that the latest versions are always installed.' )
1870
+            ),
1871
+            'actions'     => '',
1872
+            'test'        => 'plugin_theme_auto_updates',
1873
+        );
1874
+
1875
+        $check_plugin_theme_updates = $this->detect_plugin_theme_auto_update_issues();
1876
+
1877
+        $result['status'] = $check_plugin_theme_updates->status;
1878
+
1879
+        if ( 'good' !== $result['status'] ) {
1880
+            $result['label'] = __( 'Your site may have problems auto-updating plugins and themes' );
1881
+
1882
+            $result['description'] .= sprintf(
1883
+                '<p>%s</p>',
1884
+                $check_plugin_theme_updates->message
1885
+            );
1886
+        }
1887
+
1888
+        return $result;
1889
+    }
1890
+
1891
+    /**
1892
+     * Test if loopbacks work as expected.
1893
+     *
1894
+     * A loopback is when WordPress queries itself, for example to start a new WP_Cron instance,
1895
+     * or when editing a plugin or theme. This has shown itself to be a recurring issue,
1896
+     * as code can very easily break this interaction.
1897
+     *
1898
+     * @since 5.2.0
1899
+     *
1900
+     * @return array The test results.
1901
+     */
1902
+    public function get_test_loopback_requests() {
1903
+        $result = array(
1904
+            'label'       => __( 'Your site can perform loopback requests' ),
1905
+            'status'      => 'good',
1906
+            'badge'       => array(
1907
+                'label' => __( 'Performance' ),
1908
+                'color' => 'blue',
1909
+            ),
1910
+            'description' => sprintf(
1911
+                '<p>%s</p>',
1912
+                __( 'Loopback requests are used to run scheduled events, and are also used by the built-in editors for themes and plugins to verify code stability.' )
1913
+            ),
1914
+            'actions'     => '',
1915
+            'test'        => 'loopback_requests',
1916
+        );
1917
+
1918
+        $check_loopback = $this->can_perform_loopback();
1919
+
1920
+        $result['status'] = $check_loopback->status;
1921
+
1922
+        if ( 'good' !== $result['status'] ) {
1923
+            $result['label'] = __( 'Your site could not complete a loopback request' );
1924
+
1925
+            $result['description'] .= sprintf(
1926
+                '<p>%s</p>',
1927
+                $check_loopback->message
1928
+            );
1929
+        }
1930
+
1931
+        return $result;
1932
+    }
1933
+
1934
+    /**
1935
+     * Test if HTTP requests are blocked.
1936
+     *
1937
+     * It's possible to block all outgoing communication (with the possibility of allowing certain
1938
+     * hosts) via the HTTP API. This may create problems for users as many features are running as
1939
+     * services these days.
1940
+     *
1941
+     * @since 5.2.0
1942
+     *
1943
+     * @return array The test results.
1944
+     */
1945
+    public function get_test_http_requests() {
1946
+        $result = array(
1947
+            'label'       => __( 'HTTP requests seem to be working as expected' ),
1948
+            'status'      => 'good',
1949
+            'badge'       => array(
1950
+                'label' => __( 'Performance' ),
1951
+                'color' => 'blue',
1952
+            ),
1953
+            'description' => sprintf(
1954
+                '<p>%s</p>',
1955
+                __( 'It is possible for site maintainers to block all, or some, communication to other sites and services. If set up incorrectly, this may prevent plugins and themes from working as intended.' )
1956
+            ),
1957
+            'actions'     => '',
1958
+            'test'        => 'http_requests',
1959
+        );
1960
+
1961
+        $blocked = false;
1962
+        $hosts   = array();
1963
+
1964
+        if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
1965
+            $blocked = true;
1966
+        }
1967
+
1968
+        if ( defined( 'WP_ACCESSIBLE_HOSTS' ) ) {
1969
+            $hosts = explode( ',', WP_ACCESSIBLE_HOSTS );
1970
+        }
1971
+
1972
+        if ( $blocked && 0 === count( $hosts ) ) {
1973
+            $result['status'] = 'critical';
1974
+
1975
+            $result['label'] = __( 'HTTP requests are blocked' );
1976
+
1977
+            $result['description'] .= sprintf(
1978
+                '<p>%s</p>',
1979
+                sprintf(
1980
+                    /* translators: %s: Name of the constant used. */
1981
+                    __( 'HTTP requests have been blocked by the %s constant, with no allowed hosts.' ),
1982
+                    '<code>WP_HTTP_BLOCK_EXTERNAL</code>'
1983
+                )
1984
+            );
1985
+        }
1986
+
1987
+        if ( $blocked && 0 < count( $hosts ) ) {
1988
+            $result['status'] = 'recommended';
1989
+
1990
+            $result['label'] = __( 'HTTP requests are partially blocked' );
1991
+
1992
+            $result['description'] .= sprintf(
1993
+                '<p>%s</p>',
1994
+                sprintf(
1995
+                    /* translators: 1: Name of the constant used. 2: List of allowed hostnames. */
1996
+                    __( 'HTTP requests have been blocked by the %1$s constant, with some allowed hosts: %2$s.' ),
1997
+                    '<code>WP_HTTP_BLOCK_EXTERNAL</code>',
1998
+                    implode( ',', $hosts )
1999
+                )
2000
+            );
2001
+        }
2002
+
2003
+        return $result;
2004
+    }
2005
+
2006
+    /**
2007
+     * Test if the REST API is accessible.
2008
+     *
2009
+     * Various security measures may block the REST API from working, or it may have been disabled in general.
2010
+     * This is required for the new block editor to work, so we explicitly test for this.
2011
+     *
2012
+     * @since 5.2.0
2013
+     *
2014
+     * @return array The test results.
2015
+     */
2016
+    public function get_test_rest_availability() {
2017
+        $result = array(
2018
+            'label'       => __( 'The REST API is available' ),
2019
+            'status'      => 'good',
2020
+            'badge'       => array(
2021
+                'label' => __( 'Performance' ),
2022
+                'color' => 'blue',
2023
+            ),
2024
+            'description' => sprintf(
2025
+                '<p>%s</p>',
2026
+                __( 'The REST API is one way WordPress, and other applications, communicate with the server. One example is the block editor screen, which relies on this to display, and save, your posts and pages.' )
2027
+            ),
2028
+            'actions'     => '',
2029
+            'test'        => 'rest_availability',
2030
+        );
2031
+
2032
+        $cookies = wp_unslash( $_COOKIE );
2033
+        $timeout = 10;
2034
+        $headers = array(
2035
+            'Cache-Control' => 'no-cache',
2036
+            'X-WP-Nonce'    => wp_create_nonce( 'wp_rest' ),
2037
+        );
2038
+        /** This filter is documented in wp-includes/class-wp-http-streams.php */
2039
+        $sslverify = apply_filters( 'https_local_ssl_verify', false );
2040
+
2041
+        // Include Basic auth in loopback requests.
2042
+        if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
2043
+            $headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
2044
+        }
2045
+
2046
+        $url = rest_url( 'wp/v2/types/post' );
2047
+
2048
+        // The context for this is editing with the new block editor.
2049
+        $url = add_query_arg(
2050
+            array(
2051
+                'context' => 'edit',
2052
+            ),
2053
+            $url
2054
+        );
2055
+
2056
+        $r = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout', 'sslverify' ) );
2057
+
2058
+        if ( is_wp_error( $r ) ) {
2059
+            $result['status'] = 'critical';
2060
+
2061
+            $result['label'] = __( 'The REST API encountered an error' );
2062
+
2063
+            $result['description'] .= sprintf(
2064
+                '<p>%s</p>',
2065
+                sprintf(
2066
+                    '%s<br>%s',
2067
+                    __( 'The REST API request failed due to an error.' ),
2068
+                    sprintf(
2069
+                        /* translators: 1: The WordPress error message. 2: The WordPress error code. */
2070
+                        __( 'Error: %1$s (%2$s)' ),
2071
+                        $r->get_error_message(),
2072
+                        $r->get_error_code()
2073
+                    )
2074
+                )
2075
+            );
2076
+        } elseif ( 200 !== wp_remote_retrieve_response_code( $r ) ) {
2077
+            $result['status'] = 'recommended';
2078
+
2079
+            $result['label'] = __( 'The REST API encountered an unexpected result' );
2080
+
2081
+            $result['description'] .= sprintf(
2082
+                '<p>%s</p>',
2083
+                sprintf(
2084
+                    /* translators: 1: The HTTP error code. 2: The HTTP error message. */
2085
+                    __( 'The REST API call gave the following unexpected result: (%1$d) %2$s.' ),
2086
+                    wp_remote_retrieve_response_code( $r ),
2087
+                    esc_html( wp_remote_retrieve_body( $r ) )
2088
+                )
2089
+            );
2090
+        } else {
2091
+            $json = json_decode( wp_remote_retrieve_body( $r ), true );
2092
+
2093
+            if ( false !== $json && ! isset( $json['capabilities'] ) ) {
2094
+                $result['status'] = 'recommended';
2095
+
2096
+                $result['label'] = __( 'The REST API did not behave correctly' );
2097
+
2098
+                $result['description'] .= sprintf(
2099
+                    '<p>%s</p>',
2100
+                    sprintf(
2101
+                        /* translators: %s: The name of the query parameter being tested. */
2102
+                        __( 'The REST API did not process the %s query parameter correctly.' ),
2103
+                        '<code>context</code>'
2104
+                    )
2105
+                );
2106
+            }
2107
+        }
2108
+
2109
+        return $result;
2110
+    }
2111
+
2112
+    /**
2113
+     * Test if 'file_uploads' directive in PHP.ini is turned off.
2114
+     *
2115
+     * @since 5.5.0
2116
+     *
2117
+     * @return array The test results.
2118
+     */
2119
+    public function get_test_file_uploads() {
2120
+        $result = array(
2121
+            'label'       => __( 'Files can be uploaded' ),
2122
+            'status'      => 'good',
2123
+            'badge'       => array(
2124
+                'label' => __( 'Performance' ),
2125
+                'color' => 'blue',
2126
+            ),
2127
+            'description' => sprintf(
2128
+                '<p>%s</p>',
2129
+                sprintf(
2130
+                    /* translators: 1: file_uploads, 2: php.ini */
2131
+                    __( 'The %1$s directive in %2$s determines if uploading files is allowed on your site.' ),
2132
+                    '<code>file_uploads</code>',
2133
+                    '<code>php.ini</code>'
2134
+                )
2135
+            ),
2136
+            'actions'     => '',
2137
+            'test'        => 'file_uploads',
2138
+        );
2139
+
2140
+        if ( ! function_exists( 'ini_get' ) ) {
2141
+            $result['status']       = 'critical';
2142
+            $result['description'] .= sprintf(
2143
+                /* translators: %s: ini_get() */
2144
+                __( 'The %s function has been disabled, some media settings are unavailable because of this.' ),
2145
+                '<code>ini_get()</code>'
2146
+            );
2147
+            return $result;
2148
+        }
2149
+
2150
+        if ( empty( ini_get( 'file_uploads' ) ) ) {
2151
+            $result['status']       = 'critical';
2152
+            $result['description'] .= sprintf(
2153
+                '<p>%s</p>',
2154
+                sprintf(
2155
+                    /* translators: 1: file_uploads, 2: 0 */
2156
+                    __( '%1$s is set to %2$s. You won\'t be able to upload files on your site.' ),
2157
+                    '<code>file_uploads</code>',
2158
+                    '<code>0</code>'
2159
+                )
2160
+            );
2161
+            return $result;
2162
+        }
2163
+
2164
+        $post_max_size       = ini_get( 'post_max_size' );
2165
+        $upload_max_filesize = ini_get( 'upload_max_filesize' );
2166
+
2167
+        if ( wp_convert_hr_to_bytes( $post_max_size ) < wp_convert_hr_to_bytes( $upload_max_filesize ) ) {
2168
+            $result['label'] = sprintf(
2169
+                /* translators: 1: post_max_size, 2: upload_max_filesize */
2170
+                __( 'The "%1$s" value is smaller than "%2$s"' ),
2171
+                'post_max_size',
2172
+                'upload_max_filesize'
2173
+            );
2174
+            $result['status'] = 'recommended';
2175
+
2176
+            if ( 0 === wp_convert_hr_to_bytes( $post_max_size ) ) {
2177
+                $result['description'] = sprintf(
2178
+                    '<p>%s</p>',
2179
+                    sprintf(
2180
+                        /* translators: 1: post_max_size, 2: upload_max_filesize */
2181
+                        __( 'The setting for %1$s is currently configured as 0, this could cause some problems when trying to upload files through plugin or theme features that rely on various upload methods. It is recommended to configure this setting to a fixed value, ideally matching the value of %2$s, as some upload methods read the value 0 as either unlimited, or disabled.' ),
2182
+                        '<code>post_max_size</code>',
2183
+                        '<code>upload_max_filesize</code>'
2184
+                    )
2185
+                );
2186
+            } else {
2187
+                $result['description'] = sprintf(
2188
+                    '<p>%s</p>',
2189
+                    sprintf(
2190
+                        /* translators: 1: post_max_size, 2: upload_max_filesize */
2191
+                        __( 'The setting for %1$s is smaller than %2$s, this could cause some problems when trying to upload files.' ),
2192
+                        '<code>post_max_size</code>',
2193
+                        '<code>upload_max_filesize</code>'
2194
+                    )
2195
+                );
2196
+            }
2197
+
2198
+            return $result;
2199
+        }
2200
+
2201
+        return $result;
2202
+    }
2203
+
2204
+    /**
2205
+     * Tests if the Authorization header has the expected values.
2206
+     *
2207
+     * @since 5.6.0
2208
+     *
2209
+     * @return array
2210
+     */
2211
+    public function get_test_authorization_header() {
2212
+        $result = array(
2213
+            'label'       => __( 'The Authorization header is working as expected' ),
2214
+            'status'      => 'good',
2215
+            'badge'       => array(
2216
+                'label' => __( 'Security' ),
2217
+                'color' => 'blue',
2218
+            ),
2219
+            'description' => sprintf(
2220
+                '<p>%s</p>',
2221
+                __( 'The Authorization header comes from the third-party applications you approve. Without it, those apps cannot connect to your site.' )
2222
+            ),
2223
+            'actions'     => '',
2224
+            'test'        => 'authorization_header',
2225
+        );
2226
+
2227
+        if ( ! isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) {
2228
+            $result['label'] = __( 'The authorization header is missing' );
2229
+        } elseif ( 'user' !== $_SERVER['PHP_AUTH_USER'] || 'pwd' !== $_SERVER['PHP_AUTH_PW'] ) {
2230
+            $result['label'] = __( 'The authorization header is invalid' );
2231
+        } else {
2232
+            return $result;
2233
+        }
2234
+
2235
+        $result['status'] = 'recommended';
2236
+
2237
+        if ( ! function_exists( 'got_mod_rewrite' ) ) {
2238
+            require_once ABSPATH . 'wp-admin/includes/misc.php';
2239
+        }
2240
+
2241
+        if ( got_mod_rewrite() ) {
2242
+            $result['actions'] .= sprintf(
2243
+                '<p><a href="%s">%s</a></p>',
2244
+                esc_url( admin_url( 'options-permalink.php' ) ),
2245
+                __( 'Flush permalinks' )
2246
+            );
2247
+        } else {
2248
+            $result['actions'] .= sprintf(
2249
+                '<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
2250
+                __( 'https://developer.wordpress.org/rest-api/frequently-asked-questions/#why-is-authentication-not-working' ),
2251
+                __( 'Learn how to configure the Authorization header.' ),
2252
+                /* translators: Accessibility text. */
2253
+                __( '(opens in a new tab)' )
2254
+            );
2255
+        }
2256
+
2257
+        return $result;
2258
+    }
2259
+
2260
+    /**
2261
+     * Return a set of tests that belong to the site status page.
2262
+     *
2263
+     * Each site status test is defined here, they may be `direct` tests, that run on page load, or `async` tests
2264
+     * which will run later down the line via JavaScript calls to improve page performance and hopefully also user
2265
+     * experiences.
2266
+     *
2267
+     * @since 5.2.0
2268
+     * @since 5.6.0 Added support for `has_rest` and `permissions`.
2269
+     *
2270
+     * @return array The list of tests to run.
2271
+     */
2272
+    public static function get_tests() {
2273
+        $tests = array(
2274
+            'direct' => array(
2275
+                'wordpress_version'         => array(
2276
+                    'label' => __( 'WordPress Version' ),
2277
+                    'test'  => 'wordpress_version',
2278
+                ),
2279
+                'plugin_version'            => array(
2280
+                    'label' => __( 'Plugin Versions' ),
2281
+                    'test'  => 'plugin_version',
2282
+                ),
2283
+                'theme_version'             => array(
2284
+                    'label' => __( 'Theme Versions' ),
2285
+                    'test'  => 'theme_version',
2286
+                ),
2287
+                'php_version'               => array(
2288
+                    'label' => __( 'PHP Version' ),
2289
+                    'test'  => 'php_version',
2290
+                ),
2291
+                'php_extensions'            => array(
2292
+                    'label' => __( 'PHP Extensions' ),
2293
+                    'test'  => 'php_extensions',
2294
+                ),
2295
+                'php_default_timezone'      => array(
2296
+                    'label' => __( 'PHP Default Timezone' ),
2297
+                    'test'  => 'php_default_timezone',
2298
+                ),
2299
+                'php_sessions'              => array(
2300
+                    'label' => __( 'PHP Sessions' ),
2301
+                    'test'  => 'php_sessions',
2302
+                ),
2303
+                'sql_server'                => array(
2304
+                    'label' => __( 'Database Server version' ),
2305
+                    'test'  => 'sql_server',
2306
+                ),
2307
+                'utf8mb4_support'           => array(
2308
+                    'label' => __( 'MySQL utf8mb4 support' ),
2309
+                    'test'  => 'utf8mb4_support',
2310
+                ),
2311
+                'ssl_support'               => array(
2312
+                    'label' => __( 'Secure communication' ),
2313
+                    'test'  => 'ssl_support',
2314
+                ),
2315
+                'scheduled_events'          => array(
2316
+                    'label' => __( 'Scheduled events' ),
2317
+                    'test'  => 'scheduled_events',
2318
+                ),
2319
+                'http_requests'             => array(
2320
+                    'label' => __( 'HTTP Requests' ),
2321
+                    'test'  => 'http_requests',
2322
+                ),
2323
+                'rest_availability'         => array(
2324
+                    'label'     => __( 'REST API availability' ),
2325
+                    'test'      => 'rest_availability',
2326
+                    'skip_cron' => true,
2327
+                ),
2328
+                'debug_enabled'             => array(
2329
+                    'label' => __( 'Debugging enabled' ),
2330
+                    'test'  => 'is_in_debug_mode',
2331
+                ),
2332
+                'file_uploads'              => array(
2333
+                    'label' => __( 'File uploads' ),
2334
+                    'test'  => 'file_uploads',
2335
+                ),
2336
+                'plugin_theme_auto_updates' => array(
2337
+                    'label' => __( 'Plugin and theme auto-updates' ),
2338
+                    'test'  => 'plugin_theme_auto_updates',
2339
+                ),
2340
+            ),
2341
+            'async'  => array(
2342
+                'dotorg_communication' => array(
2343
+                    'label'             => __( 'Communication with WordPress.org' ),
2344
+                    'test'              => rest_url( 'wp-site-health/v1/tests/dotorg-communication' ),
2345
+                    'has_rest'          => true,
2346
+                    'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_dotorg_communication' ),
2347
+                ),
2348
+                'background_updates'   => array(
2349
+                    'label'             => __( 'Background updates' ),
2350
+                    'test'              => rest_url( 'wp-site-health/v1/tests/background-updates' ),
2351
+                    'has_rest'          => true,
2352
+                    'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_background_updates' ),
2353
+                ),
2354
+                'loopback_requests'    => array(
2355
+                    'label'             => __( 'Loopback request' ),
2356
+                    'test'              => rest_url( 'wp-site-health/v1/tests/loopback-requests' ),
2357
+                    'has_rest'          => true,
2358
+                    'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_loopback_requests' ),
2359
+                ),
2360
+                'https_status'         => array(
2361
+                    'label'             => __( 'HTTPS status' ),
2362
+                    'test'              => rest_url( 'wp-site-health/v1/tests/https-status' ),
2363
+                    'has_rest'          => true,
2364
+                    'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_https_status' ),
2365
+                ),
2366
+            ),
2367
+        );
2368
+
2369
+        // Conditionally include Authorization header test if the site isn't protected by Basic Auth.
2370
+        if ( ! wp_is_site_protected_by_basic_auth() ) {
2371
+            $tests['async']['authorization_header'] = array(
2372
+                'label'     => __( 'Authorization header' ),
2373
+                'test'      => rest_url( 'wp-site-health/v1/tests/authorization-header' ),
2374
+                'has_rest'  => true,
2375
+                'headers'   => array( 'Authorization' => 'Basic ' . base64_encode( 'user:pwd' ) ),
2376
+                'skip_cron' => true,
2377
+            );
2378
+        }
2379
+
2380
+        /**
2381
+         * Add or modify which site status tests are run on a site.
2382
+         *
2383
+         * The site health is determined by a set of tests based on best practices from
2384
+         * both the WordPress Hosting Team and web standards in general.
2385
+         *
2386
+         * Some sites may not have the same requirements, for example the automatic update
2387
+         * checks may be handled by a host, and are therefore disabled in core.
2388
+         * Or maybe you want to introduce a new test, is caching enabled/disabled/stale for example.
2389
+         *
2390
+         * Tests may be added either as direct, or asynchronous ones. Any test that may require some time
2391
+         * to complete should run asynchronously, to avoid extended loading periods within wp-admin.
2392
+         *
2393
+         * @since 5.2.0
2394
+         * @since 5.6.0 Added the `async_direct_test` array key for asynchronous tests.
2395
+         *              Added the `skip_cron` array key for all tests.
2396
+         *
2397
+         * @param array[] $tests {
2398
+         *     An associative array of direct and asynchronous tests.
2399
+         *
2400
+         *     @type array[] $direct {
2401
+         *         An array of direct tests.
2402
+         *
2403
+         *         @type array ...$identifier {
2404
+         *             `$identifier` should be a unique identifier for the test. Plugins and themes are encouraged to
2405
+         *             prefix test identifiers with their slug to avoid collisions between tests.
2406
+         *
2407
+         *             @type string   $label     The friendly label to identify the test.
2408
+         *             @type callable $test      The callback function that runs the test and returns its result.
2409
+         *             @type bool     $skip_cron Whether to skip this test when running as cron.
2410
+         *         }
2411
+         *     }
2412
+         *     @type array[] $async {
2413
+         *         An array of asynchronous tests.
2414
+         *
2415
+         *         @type array ...$identifier {
2416
+         *             `$identifier` should be a unique identifier for the test. Plugins and themes are encouraged to
2417
+         *             prefix test identifiers with their slug to avoid collisions between tests.
2418
+         *
2419
+         *             @type string   $label             The friendly label to identify the test.
2420
+         *             @type string   $test              An admin-ajax.php action to be called to perform the test, or
2421
+         *                                               if `$has_rest` is true, a URL to a REST API endpoint to perform
2422
+         *                                               the test.
2423
+         *             @type bool     $has_rest          Whether the `$test` property points to a REST API endpoint.
2424
+         *             @type bool     $skip_cron         Whether to skip this test when running as cron.
2425
+         *             @type callable $async_direct_test A manner of directly calling the test marked as asynchronous,
2426
+         *                                               as the scheduled event can not authenticate, and endpoints
2427
+         *                                               may require authentication.
2428
+         *         }
2429
+         *     }
2430
+         * }
2431
+         */
2432
+        $tests = apply_filters( 'site_status_tests', $tests );
2433
+
2434
+        // Ensure that the filtered tests contain the required array keys.
2435
+        $tests = array_merge(
2436
+            array(
2437
+                'direct' => array(),
2438
+                'async'  => array(),
2439
+            ),
2440
+            $tests
2441
+        );
2442
+
2443
+        return $tests;
2444
+    }
2445
+
2446
+    /**
2447
+     * Add a class to the body HTML tag.
2448
+     *
2449
+     * Filters the body class string for admin pages and adds our own class for easier styling.
2450
+     *
2451
+     * @since 5.2.0
2452
+     *
2453
+     * @param string $body_class The body class string.
2454
+     * @return string The modified body class string.
2455
+     */
2456
+    public function admin_body_class( $body_class ) {
2457
+        $screen = get_current_screen();
2458
+        if ( 'site-health' !== $screen->id ) {
2459
+            return $body_class;
2460
+        }
2461
+
2462
+        $body_class .= ' site-health';
2463
+
2464
+        return $body_class;
2465
+    }
2466
+
2467
+    /**
2468
+     * Initiate the WP_Cron schedule test cases.
2469
+     *
2470
+     * @since 5.2.0
2471
+     */
2472
+    private function wp_schedule_test_init() {
2473
+        $this->schedules = wp_get_schedules();
2474
+        $this->get_cron_tasks();
2475
+    }
2476
+
2477
+    /**
2478
+     * Populate our list of cron events and store them to a class-wide variable.
2479
+     *
2480
+     * @since 5.2.0
2481
+     */
2482
+    private function get_cron_tasks() {
2483
+        $cron_tasks = _get_cron_array();
2484
+
2485
+        if ( empty( $cron_tasks ) ) {
2486
+            $this->crons = new WP_Error( 'no_tasks', __( 'No scheduled events exist on this site.' ) );
2487
+            return;
2488
+        }
2489
+
2490
+        $this->crons = array();
2491
+
2492
+        foreach ( $cron_tasks as $time => $cron ) {
2493
+            foreach ( $cron as $hook => $dings ) {
2494
+                foreach ( $dings as $sig => $data ) {
2495
+
2496
+                    $this->crons[ "$hook-$sig-$time" ] = (object) array(
2497
+                        'hook'     => $hook,
2498
+                        'time'     => $time,
2499
+                        'sig'      => $sig,
2500
+                        'args'     => $data['args'],
2501
+                        'schedule' => $data['schedule'],
2502
+                        'interval' => isset( $data['interval'] ) ? $data['interval'] : null,
2503
+                    );
2504
+
2505
+                }
2506
+            }
2507
+        }
2508
+    }
2509
+
2510
+    /**
2511
+     * Check if any scheduled tasks have been missed.
2512
+     *
2513
+     * Returns a boolean value of `true` if a scheduled task has been missed and ends processing.
2514
+     *
2515
+     * If the list of crons is an instance of WP_Error, returns the instance instead of a boolean value.
2516
+     *
2517
+     * @since 5.2.0
2518
+     *
2519
+     * @return bool|WP_Error True if a cron was missed, false if not. WP_Error if the cron is set to that.
2520
+     */
2521
+    public function has_missed_cron() {
2522
+        if ( is_wp_error( $this->crons ) ) {
2523
+            return $this->crons;
2524
+        }
2525
+
2526
+        foreach ( $this->crons as $id => $cron ) {
2527
+            if ( ( $cron->time - time() ) < $this->timeout_missed_cron ) {
2528
+                $this->last_missed_cron = $cron->hook;
2529
+                return true;
2530
+            }
2531
+        }
2532
+
2533
+        return false;
2534
+    }
2535
+
2536
+    /**
2537
+     * Check if any scheduled tasks are late.
2538
+     *
2539
+     * Returns a boolean value of `true` if a scheduled task is late and ends processing.
2540
+     *
2541
+     * If the list of crons is an instance of WP_Error, returns the instance instead of a boolean value.
2542
+     *
2543
+     * @since 5.3.0
2544
+     *
2545
+     * @return bool|WP_Error True if a cron is late, false if not. WP_Error if the cron is set to that.
2546
+     */
2547
+    public function has_late_cron() {
2548
+        if ( is_wp_error( $this->crons ) ) {
2549
+            return $this->crons;
2550
+        }
2551
+
2552
+        foreach ( $this->crons as $id => $cron ) {
2553
+            $cron_offset = $cron->time - time();
2554
+            if (
2555
+                $cron_offset >= $this->timeout_missed_cron &&
2556
+                $cron_offset < $this->timeout_late_cron
2557
+            ) {
2558
+                $this->last_late_cron = $cron->hook;
2559
+                return true;
2560
+            }
2561
+        }
2562
+
2563
+        return false;
2564
+    }
2565
+
2566
+    /**
2567
+     * Check for potential issues with plugin and theme auto-updates.
2568
+     *
2569
+     * Though there is no way to 100% determine if plugin and theme auto-updates are configured
2570
+     * correctly, a few educated guesses could be made to flag any conditions that would
2571
+     * potentially cause unexpected behaviors.
2572
+     *
2573
+     * @since 5.5.0
2574
+     *
2575
+     * @return object The test results.
2576
+     */
2577
+    public function detect_plugin_theme_auto_update_issues() {
2578
+        $mock_plugin = (object) array(
2579
+            'id'            => 'w.org/plugins/a-fake-plugin',
2580
+            'slug'          => 'a-fake-plugin',
2581
+            'plugin'        => 'a-fake-plugin/a-fake-plugin.php',
2582
+            'new_version'   => '9.9',
2583
+            'url'           => 'https://wordpress.org/plugins/a-fake-plugin/',
2584
+            'package'       => 'https://downloads.wordpress.org/plugin/a-fake-plugin.9.9.zip',
2585
+            'icons'         => array(
2586
+                '2x' => 'https://ps.w.org/a-fake-plugin/assets/icon-256x256.png',
2587
+                '1x' => 'https://ps.w.org/a-fake-plugin/assets/icon-128x128.png',
2588
+            ),
2589
+            'banners'       => array(
2590
+                '2x' => 'https://ps.w.org/a-fake-plugin/assets/banner-1544x500.png',
2591
+                '1x' => 'https://ps.w.org/a-fake-plugin/assets/banner-772x250.png',
2592
+            ),
2593
+            'banners_rtl'   => array(),
2594
+            'tested'        => '5.5.0',
2595
+            'requires_php'  => '5.6.20',
2596
+            'compatibility' => new stdClass(),
2597
+        );
2598
+
2599
+        $mock_theme = (object) array(
2600
+            'theme'        => 'a-fake-theme',
2601
+            'new_version'  => '9.9',
2602
+            'url'          => 'https://wordpress.org/themes/a-fake-theme/',
2603
+            'package'      => 'https://downloads.wordpress.org/theme/a-fake-theme.9.9.zip',
2604
+            'requires'     => '5.0.0',
2605
+            'requires_php' => '5.6.20',
2606
+        );
2607
+
2608
+        $test_plugins_enabled = wp_is_auto_update_forced_for_item( 'plugin', true, $mock_plugin );
2609
+        $test_themes_enabled  = wp_is_auto_update_forced_for_item( 'theme', true, $mock_theme );
2610
+
2611
+        $ui_enabled_for_plugins = wp_is_auto_update_enabled_for_type( 'plugin' );
2612
+        $ui_enabled_for_themes  = wp_is_auto_update_enabled_for_type( 'theme' );
2613
+        $plugin_filter_present  = has_filter( 'auto_update_plugin' );
2614
+        $theme_filter_present   = has_filter( 'auto_update_theme' );
2615
+
2616
+        if ( ( ! $test_plugins_enabled && $ui_enabled_for_plugins )
2617
+            || ( ! $test_themes_enabled && $ui_enabled_for_themes )
2618
+        ) {
2619
+            return (object) array(
2620
+                'status'  => 'critical',
2621
+                'message' => __( 'Auto-updates for plugins and/or themes appear to be disabled, but settings are still set to be displayed. This could cause auto-updates to not work as expected.' ),
2622
+            );
2623
+        }
2624
+
2625
+        if ( ( ! $test_plugins_enabled && $plugin_filter_present )
2626
+            && ( ! $test_themes_enabled && $theme_filter_present )
2627
+        ) {
2628
+            return (object) array(
2629
+                'status'  => 'recommended',
2630
+                'message' => __( 'Auto-updates for plugins and themes appear to be disabled. This will prevent your site from receiving new versions automatically when available.' ),
2631
+            );
2632
+        } elseif ( ! $test_plugins_enabled && $plugin_filter_present ) {
2633
+            return (object) array(
2634
+                'status'  => 'recommended',
2635
+                'message' => __( 'Auto-updates for plugins appear to be disabled. This will prevent your site from receiving new versions automatically when available.' ),
2636
+            );
2637
+        } elseif ( ! $test_themes_enabled && $theme_filter_present ) {
2638
+            return (object) array(
2639
+                'status'  => 'recommended',
2640
+                'message' => __( 'Auto-updates for themes appear to be disabled. This will prevent your site from receiving new versions automatically when available.' ),
2641
+            );
2642
+        }
2643
+
2644
+        return (object) array(
2645
+            'status'  => 'good',
2646
+            'message' => __( 'There appear to be no issues with plugin and theme auto-updates.' ),
2647
+        );
2648
+    }
2649
+
2650
+    /**
2651
+     * Run a loopback test on our site.
2652
+     *
2653
+     * Loopbacks are what WordPress uses to communicate with itself to start up WP_Cron, scheduled posts,
2654
+     * make sure plugin or theme edits don't cause site failures and similar.
2655
+     *
2656
+     * @since 5.2.0
2657
+     *
2658
+     * @return object The test results.
2659
+     */
2660
+    public function can_perform_loopback() {
2661
+        $body    = array( 'site-health' => 'loopback-test' );
2662
+        $cookies = wp_unslash( $_COOKIE );
2663
+        $timeout = 10;
2664
+        $headers = array(
2665
+            'Cache-Control' => 'no-cache',
2666
+        );
2667
+        /** This filter is documented in wp-includes/class-wp-http-streams.php */
2668
+        $sslverify = apply_filters( 'https_local_ssl_verify', false );
2669
+
2670
+        // Include Basic auth in loopback requests.
2671
+        if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
2672
+            $headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
2673
+        }
2674
+
2675
+        $url = site_url( 'wp-cron.php' );
2676
+
2677
+        /*
2678 2678
 		 * A post request is used for the wp-cron.php loopback test to cause the file
2679 2679
 		 * to finish early without triggering cron jobs. This has two benefits:
2680 2680
 		 * - cron jobs are not triggered a second time on the site health page,
@@ -2684,172 +2684,172 @@  discard block
 block discarded – undo
2684 2684
 		 * GET request WordPress uses for wp-cron.php loopback requests but is close
2685 2685
 		 * enough. See https://core.trac.wordpress.org/ticket/52547
2686 2686
 		 */
2687
-		$r = wp_remote_post( $url, compact( 'body', 'cookies', 'headers', 'timeout', 'sslverify' ) );
2688
-
2689
-		if ( is_wp_error( $r ) ) {
2690
-			return (object) array(
2691
-				'status'  => 'critical',
2692
-				'message' => sprintf(
2693
-					'%s<br>%s',
2694
-					__( 'The loopback request to your site failed, this means features relying on them are not currently working as expected.' ),
2695
-					sprintf(
2696
-						/* translators: 1: The WordPress error message. 2: The WordPress error code. */
2697
-						__( 'Error: %1$s (%2$s)' ),
2698
-						$r->get_error_message(),
2699
-						$r->get_error_code()
2700
-					)
2701
-				),
2702
-			);
2703
-		}
2704
-
2705
-		if ( 200 !== wp_remote_retrieve_response_code( $r ) ) {
2706
-			return (object) array(
2707
-				'status'  => 'recommended',
2708
-				'message' => sprintf(
2709
-					/* translators: %d: The HTTP response code returned. */
2710
-					__( 'The loopback request returned an unexpected http status code, %d, it was not possible to determine if this will prevent features from working as expected.' ),
2711
-					wp_remote_retrieve_response_code( $r )
2712
-				),
2713
-			);
2714
-		}
2715
-
2716
-		return (object) array(
2717
-			'status'  => 'good',
2718
-			'message' => __( 'The loopback request to your site completed successfully.' ),
2719
-		);
2720
-	}
2721
-
2722
-	/**
2723
-	 * Create a weekly cron event, if one does not already exist.
2724
-	 *
2725
-	 * @since 5.4.0
2726
-	 */
2727
-	public function maybe_create_scheduled_event() {
2728
-		if ( ! wp_next_scheduled( 'wp_site_health_scheduled_check' ) && ! wp_installing() ) {
2729
-			wp_schedule_event( time() + DAY_IN_SECONDS, 'weekly', 'wp_site_health_scheduled_check' );
2730
-		}
2731
-	}
2732
-
2733
-	/**
2734
-	 * Run our scheduled event to check and update the latest site health status for the website.
2735
-	 *
2736
-	 * @since 5.4.0
2737
-	 */
2738
-	public function wp_cron_scheduled_check() {
2739
-		// Bootstrap wp-admin, as WP_Cron doesn't do this for us.
2740
-		require_once trailingslashit( ABSPATH ) . 'wp-admin/includes/admin.php';
2741
-
2742
-		$tests = WP_Site_Health::get_tests();
2743
-
2744
-		$results = array();
2745
-
2746
-		$site_status = array(
2747
-			'good'        => 0,
2748
-			'recommended' => 0,
2749
-			'critical'    => 0,
2750
-		);
2751
-
2752
-		// Don't run https test on development environments.
2753
-		if ( $this->is_development_environment() ) {
2754
-			unset( $tests['async']['https_status'] );
2755
-		}
2756
-
2757
-		foreach ( $tests['direct'] as $test ) {
2758
-			if ( ! empty( $test['skip_cron'] ) ) {
2759
-				continue;
2760
-			}
2761
-
2762
-			if ( is_string( $test['test'] ) ) {
2763
-				$test_function = sprintf(
2764
-					'get_test_%s',
2765
-					$test['test']
2766
-				);
2767
-
2768
-				if ( method_exists( $this, $test_function ) && is_callable( array( $this, $test_function ) ) ) {
2769
-					$results[] = $this->perform_test( array( $this, $test_function ) );
2770
-					continue;
2771
-				}
2772
-			}
2773
-
2774
-			if ( is_callable( $test['test'] ) ) {
2775
-				$results[] = $this->perform_test( $test['test'] );
2776
-			}
2777
-		}
2778
-
2779
-		foreach ( $tests['async'] as $test ) {
2780
-			if ( ! empty( $test['skip_cron'] ) ) {
2781
-				continue;
2782
-			}
2783
-
2784
-			// Local endpoints may require authentication, so asynchronous tests can pass a direct test runner as well.
2785
-			if ( ! empty( $test['async_direct_test'] ) && is_callable( $test['async_direct_test'] ) ) {
2786
-				// This test is callable, do so and continue to the next asynchronous check.
2787
-				$results[] = $this->perform_test( $test['async_direct_test'] );
2788
-				continue;
2789
-			}
2790
-
2791
-			if ( is_string( $test['test'] ) ) {
2792
-				// Check if this test has a REST API endpoint.
2793
-				if ( isset( $test['has_rest'] ) && $test['has_rest'] ) {
2794
-					$result_fetch = wp_remote_get(
2795
-						$test['test'],
2796
-						array(
2797
-							'body' => array(
2798
-								'_wpnonce' => wp_create_nonce( 'wp_rest' ),
2799
-							),
2800
-						)
2801
-					);
2802
-				} else {
2803
-					$result_fetch = wp_remote_post(
2804
-						admin_url( 'admin-ajax.php' ),
2805
-						array(
2806
-							'body' => array(
2807
-								'action'   => $test['test'],
2808
-								'_wpnonce' => wp_create_nonce( 'health-check-site-status' ),
2809
-							),
2810
-						)
2811
-					);
2812
-				}
2813
-
2814
-				if ( ! is_wp_error( $result_fetch ) && 200 === wp_remote_retrieve_response_code( $result_fetch ) ) {
2815
-					$result = json_decode( wp_remote_retrieve_body( $result_fetch ), true );
2816
-				} else {
2817
-					$result = false;
2818
-				}
2819
-
2820
-				if ( is_array( $result ) ) {
2821
-					$results[] = $result;
2822
-				} else {
2823
-					$results[] = array(
2824
-						'status' => 'recommended',
2825
-						'label'  => __( 'A test is unavailable' ),
2826
-					);
2827
-				}
2828
-			}
2829
-		}
2830
-
2831
-		foreach ( $results as $result ) {
2832
-			if ( 'critical' === $result['status'] ) {
2833
-				$site_status['critical']++;
2834
-			} elseif ( 'recommended' === $result['status'] ) {
2835
-				$site_status['recommended']++;
2836
-			} else {
2837
-				$site_status['good']++;
2838
-			}
2839
-		}
2840
-
2841
-		set_transient( 'health-check-site-status-result', wp_json_encode( $site_status ) );
2842
-	}
2843
-
2844
-	/**
2845
-	 * Checks if the current environment type is set to 'development' or 'local'.
2846
-	 *
2847
-	 * @since 5.6.0
2848
-	 *
2849
-	 * @return bool True if it is a development environment, false if not.
2850
-	 */
2851
-	public function is_development_environment() {
2852
-		return in_array( wp_get_environment_type(), array( 'development', 'local' ), true );
2853
-	}
2687
+        $r = wp_remote_post( $url, compact( 'body', 'cookies', 'headers', 'timeout', 'sslverify' ) );
2688
+
2689
+        if ( is_wp_error( $r ) ) {
2690
+            return (object) array(
2691
+                'status'  => 'critical',
2692
+                'message' => sprintf(
2693
+                    '%s<br>%s',
2694
+                    __( 'The loopback request to your site failed, this means features relying on them are not currently working as expected.' ),
2695
+                    sprintf(
2696
+                        /* translators: 1: The WordPress error message. 2: The WordPress error code. */
2697
+                        __( 'Error: %1$s (%2$s)' ),
2698
+                        $r->get_error_message(),
2699
+                        $r->get_error_code()
2700
+                    )
2701
+                ),
2702
+            );
2703
+        }
2704
+
2705
+        if ( 200 !== wp_remote_retrieve_response_code( $r ) ) {
2706
+            return (object) array(
2707
+                'status'  => 'recommended',
2708
+                'message' => sprintf(
2709
+                    /* translators: %d: The HTTP response code returned. */
2710
+                    __( 'The loopback request returned an unexpected http status code, %d, it was not possible to determine if this will prevent features from working as expected.' ),
2711
+                    wp_remote_retrieve_response_code( $r )
2712
+                ),
2713
+            );
2714
+        }
2715
+
2716
+        return (object) array(
2717
+            'status'  => 'good',
2718
+            'message' => __( 'The loopback request to your site completed successfully.' ),
2719
+        );
2720
+    }
2721
+
2722
+    /**
2723
+     * Create a weekly cron event, if one does not already exist.
2724
+     *
2725
+     * @since 5.4.0
2726
+     */
2727
+    public function maybe_create_scheduled_event() {
2728
+        if ( ! wp_next_scheduled( 'wp_site_health_scheduled_check' ) && ! wp_installing() ) {
2729
+            wp_schedule_event( time() + DAY_IN_SECONDS, 'weekly', 'wp_site_health_scheduled_check' );
2730
+        }
2731
+    }
2732
+
2733
+    /**
2734
+     * Run our scheduled event to check and update the latest site health status for the website.
2735
+     *
2736
+     * @since 5.4.0
2737
+     */
2738
+    public function wp_cron_scheduled_check() {
2739
+        // Bootstrap wp-admin, as WP_Cron doesn't do this for us.
2740
+        require_once trailingslashit( ABSPATH ) . 'wp-admin/includes/admin.php';
2741
+
2742
+        $tests = WP_Site_Health::get_tests();
2743
+
2744
+        $results = array();
2745
+
2746
+        $site_status = array(
2747
+            'good'        => 0,
2748
+            'recommended' => 0,
2749
+            'critical'    => 0,
2750
+        );
2751
+
2752
+        // Don't run https test on development environments.
2753
+        if ( $this->is_development_environment() ) {
2754
+            unset( $tests['async']['https_status'] );
2755
+        }
2756
+
2757
+        foreach ( $tests['direct'] as $test ) {
2758
+            if ( ! empty( $test['skip_cron'] ) ) {
2759
+                continue;
2760
+            }
2761
+
2762
+            if ( is_string( $test['test'] ) ) {
2763
+                $test_function = sprintf(
2764
+                    'get_test_%s',
2765
+                    $test['test']
2766
+                );
2767
+
2768
+                if ( method_exists( $this, $test_function ) && is_callable( array( $this, $test_function ) ) ) {
2769
+                    $results[] = $this->perform_test( array( $this, $test_function ) );
2770
+                    continue;
2771
+                }
2772
+            }
2773
+
2774
+            if ( is_callable( $test['test'] ) ) {
2775
+                $results[] = $this->perform_test( $test['test'] );
2776
+            }
2777
+        }
2778
+
2779
+        foreach ( $tests['async'] as $test ) {
2780
+            if ( ! empty( $test['skip_cron'] ) ) {
2781
+                continue;
2782
+            }
2783
+
2784
+            // Local endpoints may require authentication, so asynchronous tests can pass a direct test runner as well.
2785
+            if ( ! empty( $test['async_direct_test'] ) && is_callable( $test['async_direct_test'] ) ) {
2786
+                // This test is callable, do so and continue to the next asynchronous check.
2787
+                $results[] = $this->perform_test( $test['async_direct_test'] );
2788
+                continue;
2789
+            }
2790
+
2791
+            if ( is_string( $test['test'] ) ) {
2792
+                // Check if this test has a REST API endpoint.
2793
+                if ( isset( $test['has_rest'] ) && $test['has_rest'] ) {
2794
+                    $result_fetch = wp_remote_get(
2795
+                        $test['test'],
2796
+                        array(
2797
+                            'body' => array(
2798
+                                '_wpnonce' => wp_create_nonce( 'wp_rest' ),
2799
+                            ),
2800
+                        )
2801
+                    );
2802
+                } else {
2803
+                    $result_fetch = wp_remote_post(
2804
+                        admin_url( 'admin-ajax.php' ),
2805
+                        array(
2806
+                            'body' => array(
2807
+                                'action'   => $test['test'],
2808
+                                '_wpnonce' => wp_create_nonce( 'health-check-site-status' ),
2809
+                            ),
2810
+                        )
2811
+                    );
2812
+                }
2813
+
2814
+                if ( ! is_wp_error( $result_fetch ) && 200 === wp_remote_retrieve_response_code( $result_fetch ) ) {
2815
+                    $result = json_decode( wp_remote_retrieve_body( $result_fetch ), true );
2816
+                } else {
2817
+                    $result = false;
2818
+                }
2819
+
2820
+                if ( is_array( $result ) ) {
2821
+                    $results[] = $result;
2822
+                } else {
2823
+                    $results[] = array(
2824
+                        'status' => 'recommended',
2825
+                        'label'  => __( 'A test is unavailable' ),
2826
+                    );
2827
+                }
2828
+            }
2829
+        }
2830
+
2831
+        foreach ( $results as $result ) {
2832
+            if ( 'critical' === $result['status'] ) {
2833
+                $site_status['critical']++;
2834
+            } elseif ( 'recommended' === $result['status'] ) {
2835
+                $site_status['recommended']++;
2836
+            } else {
2837
+                $site_status['good']++;
2838
+            }
2839
+        }
2840
+
2841
+        set_transient( 'health-check-site-status-result', wp_json_encode( $site_status ) );
2842
+    }
2843
+
2844
+    /**
2845
+     * Checks if the current environment type is set to 'development' or 'local'.
2846
+     *
2847
+     * @since 5.6.0
2848
+     *
2849
+     * @return bool True if it is a development environment, false if not.
2850
+     */
2851
+    public function is_development_environment() {
2852
+        return in_array( wp_get_environment_type(), array( 'development', 'local' ), true );
2853
+    }
2854 2854
 
2855 2855
 }
Please login to merge, or discard this patch.