From 5ffe591bec0d1c6109c3b7fb1abe698c74b2b5df Mon Sep 17 00:00:00 2001 From: Jake Spurlock Date: Tue, 21 Jul 2020 15:19:58 +0000 Subject: [PATCH] Site Health: Include new tests to check for the ability to upload files. Several new checks: * `max_file_uploads` * `file_uploads` * `post_max_size` * `upload_max_filesize` * `upload_max` * `max_file_uploads` In addition, new function `parse_ini_size()` that converts shorthand byte strings to bytes. Useful for size comparisons. Fixes #50038. Props dd32, donmhico, JavierCasares, SergeyBiryukov, ayeshrajans, Clorith, ipstenu, sabernhardt, whyisjake. git-svn-id: https://develop.svn.wordpress.org/trunk@48535 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-wp-debug-data.php | 41 ++++++++++ .../includes/class-wp-site-health.php | 74 +++++++++++++++++++ src/wp-includes/functions.php | 32 ++++++++ 3 files changed, 147 insertions(+) diff --git a/src/wp-admin/includes/class-wp-debug-data.php b/src/wp-admin/includes/class-wp-debug-data.php index ab058d02e1..e26e2ed5d2 100644 --- a/src/wp-admin/includes/class-wp-debug-data.php +++ b/src/wp-admin/includes/class-wp-debug-data.php @@ -519,6 +519,47 @@ class WP_Debug_Data { 'value' => ( is_array( $imagick_version ) ? $imagick_version['versionString'] : $imagick_version ), ); + if ( ! function_exists( 'ini_get' ) ) { + $info['wp-media']['fields']['ini_get'] = array( + 'label' => __( 'File upload settings' ), + 'value' => sprintf( + /* translators: %s: ini_get() */ + __( 'Unable to determine some settings, as the %s function has been disabled.' ), + 'ini_get()' + ), + 'debug' => 'ini_get() is disabled', + ); + } else { + // Get the PHP ini directive values. + $post_max_size = ini_get( 'post_max_size' ); + $upload_max_size = ini_get( 'upload_max_filesize' ); + $max_file_uploads = ini_get( 'max_file_uploads' ); + $effective = min( parse_ini_size( $post_max_size ), parse_ini_size( $upload_max_size ) ); + + // Add info in Media section. + $info['wp-media']['fields']['file_uploads'] = array( + 'label' => __( 'File uploads' ), + 'value' => empty( ini_get( 'file_uploads' ) ) ? __( 'Disabled' ) : __( 'Enabled' ), + 'debug' => 'File uploads is turned off', + ); + $info['wp-media']['fields']['post_max_size'] = array( + 'label' => __( 'Max size of post data allowed' ), + 'value' => $post_max_size, + ); + $info['wp-media']['fields']['upload_max_filesize'] = array( + 'label' => __( 'Max size of an uploaded file' ), + 'value' => $upload_max_size, + ); + $info['wp-media']['fields']['upload_max'] = array( + 'label' => __( 'Max effective file size' ), + 'value' => size_format( $effective ), + ); + $info['wp-media']['fields']['max_file_uploads'] = array( + 'label' => __( 'Max number of files allowed' ), + 'value' => number_format( $max_file_uploads ), + ); + } + // If Imagick is used as our editor, provide some more information about its limitations. if ( 'WP_Image_Editor_Imagick' === _wp_image_editor_choose() && isset( $imagick ) && $imagick instanceof Imagick ) { $limits = array( diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index bb8237a44e..f3f1898de1 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -1955,6 +1955,76 @@ class WP_Site_Health { return $result; } + /** + * Test if 'file_uploads' directive in PHP.ini is turned off + * + * @since 5.5.0 + * + * @return array The test results. + */ + public function get_test_file_uploads() { + $result = array( + 'label' => __( 'Files can be uploaded.' ), + 'status' => 'good', + 'badge' => array( + 'label' => __( 'Performance' ), + 'color' => 'blue', + ), + 'description' => sprintf( + '

%s

', + sprintf( + /* translators: %1$s: file_uploads %2$s: php.ini */ + __( 'The %1$s directive in %2$s determines if uploading to is allowed in your WordPress.' ), + 'file_uploads', + 'php.ini' + ) + ), + 'actions' => '', + 'test' => 'file_uploads', + ); + + if ( ! function_exists( 'ini_get' ) ) { + $result['status'] = 'critical'; + $result['description'] .= sprintf( + /* translators: %s: ini_get() */ + __( 'The %s function has been disabled, some media settings are unavailable because of this.' ), + 'ini_get()' + ); + return $result; + } + + if ( empty( ini_get( 'file_uploads' ) ) ) { + $result['status'] = 'critical'; + $result['description'] .= sprintf( + '

%s

', + sprintf( + /* translators: %1$s: file_uploads %2$s: 0 */ + __( '%1$s is set to %2$s. You won\'t be able to upload files in your WordPress.' ), + 'file_uploads', + '0' + ) + ); + return $result; + } + + if ( parse_ini_size( ini_get( 'post_max_size' ) ) !== parse_ini_size( ini_get( 'upload_max_filesize' ) ) ) { + $result['label'] = __( 'Mismatched "post_max_size" and "upload_max_filesize" values.' ); + $result['status'] = 'recommended'; + $result['description'] = sprintf( + '

%s

', + sprintf( + /* translators: %1$s: post_max_size %2$s: upload_max_filesize */ + __( 'The settings for %1$s and %2$s are not the same, this could cause some problems when trying to upload files.' ), + 'post_max_size', + 'upload_max_filesize' + ) + ); + return $result; + } + + return $result; + } + /** * Return a set of tests that belong to the site status page. * @@ -2025,6 +2095,10 @@ class WP_Site_Health { 'label' => __( 'Debugging enabled' ), 'test' => 'is_in_debug_mode', ), + 'file_uploads' => array( + 'label' => __( 'File uploads' ), + 'test' => 'file_uploads', + ), ), 'async' => array( 'dotorg_communication' => array( diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 3c0937ed32..4b58181259 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -476,6 +476,38 @@ function size_format( $bytes, $decimals = 0 ) { return false; } +/** + * Converts a shorthand byte string to bytes. + * + * Useful when needing to compare two byte strings for size differences. + * + * E.g. + * "1G" (1 Gigabyte) = 1073741824 + * "10M" (10 Megabytes) = 10485760 + * "1K" (1 Kilobyte) = 1024 + * + * @since 5.5.0 + * + * @param string $size_string Shorthand byte string + * @return int $size_string converted to numberic bytes. + */ +function parse_ini_size( $size_string ) { + $size_string = trim( $size_string ); + $last = strtolower( substr( $size_string, - 1 ) ); + $value = intval( $size_string ); + + switch ( $last ) { + case 'g': + return (int) $value * GB_IN_BYTES; + case 'm': + return (int) $value * MB_IN_BYTES; + case 'k': + return (int) $value * KB_IN_BYTES; + default: + return (int) $value; + } +} + /** * Convert a duration to human readable format. *