8 require ABSPATH . WPINC . '/option.php'; |
8 require ABSPATH . WPINC . '/option.php'; |
9 |
9 |
10 /** |
10 /** |
11 * Convert given MySQL date string into a different format. |
11 * Convert given MySQL date string into a different format. |
12 * |
12 * |
13 * `$format` should be a PHP date format string. |
13 * - `$format` should be a PHP date format string. |
14 * 'U' and 'G' formats will return a sum of timestamp with timezone offset. |
14 * - 'U' and 'G' formats will return an integer sum of timestamp with timezone offset. |
15 * `$date` is expected to be local time in MySQL format (`Y-m-d H:i:s`). |
15 * - `$date` is expected to be local time in MySQL format (`Y-m-d H:i:s`). |
16 * |
16 * |
17 * Historically UTC time could be passed to the function to produce Unix timestamp. |
17 * Historically UTC time could be passed to the function to produce Unix timestamp. |
18 * |
18 * |
19 * If `$translate` is true then the given date and format string will |
19 * If `$translate` is true then the given date and format string will |
20 * be passed to `wp_date()` for translation. |
20 * be passed to `wp_date()` for translation. |
51 } |
51 } |
52 |
52 |
53 /** |
53 /** |
54 * Retrieves the current time based on specified type. |
54 * Retrieves the current time based on specified type. |
55 * |
55 * |
56 * The 'mysql' type will return the time in the format for MySQL DATETIME field. |
56 * - The 'mysql' type will return the time in the format for MySQL DATETIME field. |
57 * The 'timestamp' type will return the current timestamp or a sum of timestamp |
57 * - The 'timestamp' or 'U' types will return the current timestamp or a sum of timestamp |
58 * and timezone offset, depending on `$gmt`. |
58 * and timezone offset, depending on `$gmt`. |
59 * Other strings will be interpreted as PHP date formats (e.g. 'Y-m-d'). |
59 * - Other strings will be interpreted as PHP date formats (e.g. 'Y-m-d'). |
60 * |
60 * |
61 * If $gmt is set to either '1' or 'true', then both types will use GMT time. |
61 * If `$gmt` is a truthy value then both types will use GMT time, otherwise the |
62 * if $gmt is false, the output is adjusted with the GMT offset in the WordPress option. |
62 * output is adjusted with the GMT offset for the site. |
63 * |
63 * |
64 * @since 1.0.0 |
64 * @since 1.0.0 |
65 * |
65 * @since 5.3.0 Now returns an integer if `$type` is 'U'. Previously a string was returned. |
66 * @param string $type Type of time to retrieve. Accepts 'mysql', 'timestamp', |
66 * |
|
67 * @param string $type Type of time to retrieve. Accepts 'mysql', 'timestamp', 'U', |
67 * or PHP date format string (e.g. 'Y-m-d'). |
68 * or PHP date format string (e.g. 'Y-m-d'). |
68 * @param int|bool $gmt Optional. Whether to use GMT timezone. Default false. |
69 * @param int|bool $gmt Optional. Whether to use GMT timezone. Default false. |
69 * @return int|string Integer if $type is 'timestamp', string otherwise. |
70 * @return int|string Integer if `$type` is 'timestamp' or 'U', string otherwise. |
70 */ |
71 */ |
71 function current_time( $type, $gmt = 0 ) { |
72 function current_time( $type, $gmt = 0 ) { |
72 // Don't use non-GMT timestamp, unless you know the difference and really need to. |
73 // Don't use non-GMT timestamp, unless you know the difference and really need to. |
73 if ( 'timestamp' === $type || 'U' === $type ) { |
74 if ( 'timestamp' === $type || 'U' === $type ) { |
74 return $gmt ? time() : time() + (int) ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); |
75 return $gmt ? time() : time() + (int) ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ); |
83 |
84 |
84 return $datetime->format( $type ); |
85 return $datetime->format( $type ); |
85 } |
86 } |
86 |
87 |
87 /** |
88 /** |
88 * Retrieves the current time as an object with the timezone from settings. |
89 * Retrieves the current time as an object using the site's timezone. |
89 * |
90 * |
90 * @since 5.3.0 |
91 * @since 5.3.0 |
91 * |
92 * |
92 * @return DateTimeImmutable Date and time object. |
93 * @return DateTimeImmutable Date and time object. |
93 */ |
94 */ |
94 function current_datetime() { |
95 function current_datetime() { |
95 return new DateTimeImmutable( 'now', wp_timezone() ); |
96 return new DateTimeImmutable( 'now', wp_timezone() ); |
96 } |
97 } |
97 |
98 |
98 /** |
99 /** |
99 * Retrieves the timezone from site settings as a string. |
100 * Retrieves the timezone of the site as a string. |
100 * |
101 * |
101 * Uses the `timezone_string` option to get a proper timezone if available, |
102 * Uses the `timezone_string` option to get a proper timezone name if available, |
102 * otherwise falls back to an offset. |
103 * otherwise falls back to a manual UTC ± offset. |
|
104 * |
|
105 * Example return values: |
|
106 * |
|
107 * - 'Europe/Rome' |
|
108 * - 'America/North_Dakota/New_Salem' |
|
109 * - 'UTC' |
|
110 * - '-06:30' |
|
111 * - '+00:00' |
|
112 * - '+08:45' |
103 * |
113 * |
104 * @since 5.3.0 |
114 * @since 5.3.0 |
105 * |
115 * |
106 * @return string PHP timezone string or a ±HH:MM offset. |
116 * @return string PHP timezone name or a ±HH:MM offset. |
107 */ |
117 */ |
108 function wp_timezone_string() { |
118 function wp_timezone_string() { |
109 $timezone_string = get_option( 'timezone_string' ); |
119 $timezone_string = get_option( 'timezone_string' ); |
110 |
120 |
111 if ( $timezone_string ) { |
121 if ( $timezone_string ) { |
165 function date_i18n( $format, $timestamp_with_offset = false, $gmt = false ) { |
175 function date_i18n( $format, $timestamp_with_offset = false, $gmt = false ) { |
166 $timestamp = $timestamp_with_offset; |
176 $timestamp = $timestamp_with_offset; |
167 |
177 |
168 // If timestamp is omitted it should be current time (summed with offset, unless `$gmt` is true). |
178 // If timestamp is omitted it should be current time (summed with offset, unless `$gmt` is true). |
169 if ( ! is_numeric( $timestamp ) ) { |
179 if ( ! is_numeric( $timestamp ) ) { |
|
180 // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested |
170 $timestamp = current_time( 'timestamp', $gmt ); |
181 $timestamp = current_time( 'timestamp', $gmt ); |
171 } |
182 } |
172 |
183 |
173 /* |
184 /* |
174 * This is a legacy implementation quirk that the returned timestamp is also with offset. |
185 * This is a legacy implementation quirk that the returned timestamp is also with offset. |
426 */ |
439 */ |
427 return apply_filters( 'number_format_i18n', $formatted, $number, $decimals ); |
440 return apply_filters( 'number_format_i18n', $formatted, $number, $decimals ); |
428 } |
441 } |
429 |
442 |
430 /** |
443 /** |
431 * Convert number of bytes largest unit bytes will fit into. |
444 * Converts a number of bytes to the largest unit the bytes will fit into. |
432 * |
445 * |
433 * It is easier to read 1 KB than 1024 bytes and 1 MB than 1048576 bytes. Converts |
446 * It is easier to read 1 KB than 1024 bytes and 1 MB than 1048576 bytes. Converts |
434 * number of bytes to human readable number by taking the number of that unit |
447 * number of bytes to human readable number by taking the number of that unit |
435 * that the bytes will go into it. Supports TB value. |
448 * that the bytes will go into it. Supports YB value. |
436 * |
449 * |
437 * Please note that integers in PHP are limited to 32 bits, unless they are on |
450 * Please note that integers in PHP are limited to 32 bits, unless they are on |
438 * 64 bit architecture, then they have 64 bit size. If you need to place the |
451 * 64 bit architecture, then they have 64 bit size. If you need to place the |
439 * larger size then what PHP integer type will hold, then use a string. It will |
452 * larger size then what PHP integer type will hold, then use a string. It will |
440 * be converted to a double, which should always have 64 bit length. |
453 * be converted to a double, which should always have 64 bit length. |
441 * |
454 * |
442 * Technically the correct unit names for powers of 1024 are KiB, MiB etc. |
455 * Technically the correct unit names for powers of 1024 are KiB, MiB etc. |
443 * |
456 * |
444 * @since 2.3.0 |
457 * @since 2.3.0 |
|
458 * @since 6.0.0 Support for PB, EB, ZB, and YB was added. |
445 * |
459 * |
446 * @param int|string $bytes Number of bytes. Note max integer size for integers. |
460 * @param int|string $bytes Number of bytes. Note max integer size for integers. |
447 * @param int $decimals Optional. Precision of number of decimal places. Default 0. |
461 * @param int $decimals Optional. Precision of number of decimal places. Default 0. |
448 * @return string|false Number string on success, false on failure. |
462 * @return string|false Number string on success, false on failure. |
449 */ |
463 */ |
450 function size_format( $bytes, $decimals = 0 ) { |
464 function size_format( $bytes, $decimals = 0 ) { |
451 $quant = array( |
465 $quant = array( |
|
466 /* translators: Unit symbol for yottabyte. */ |
|
467 _x( 'YB', 'unit symbol' ) => YB_IN_BYTES, |
|
468 /* translators: Unit symbol for zettabyte. */ |
|
469 _x( 'ZB', 'unit symbol' ) => ZB_IN_BYTES, |
|
470 /* translators: Unit symbol for exabyte. */ |
|
471 _x( 'EB', 'unit symbol' ) => EB_IN_BYTES, |
|
472 /* translators: Unit symbol for petabyte. */ |
|
473 _x( 'PB', 'unit symbol' ) => PB_IN_BYTES, |
452 /* translators: Unit symbol for terabyte. */ |
474 /* translators: Unit symbol for terabyte. */ |
453 _x( 'TB', 'unit symbol' ) => TB_IN_BYTES, |
475 _x( 'TB', 'unit symbol' ) => TB_IN_BYTES, |
454 /* translators: Unit symbol for gigabyte. */ |
476 /* translators: Unit symbol for gigabyte. */ |
455 _x( 'GB', 'unit symbol' ) => GB_IN_BYTES, |
477 _x( 'GB', 'unit symbol' ) => GB_IN_BYTES, |
456 /* translators: Unit symbol for megabyte. */ |
478 /* translators: Unit symbol for megabyte. */ |
550 * |
572 * |
551 * @since 0.71 |
573 * @since 0.71 |
552 * |
574 * |
553 * @param string $mysqlstring Date or datetime field type from MySQL. |
575 * @param string $mysqlstring Date or datetime field type from MySQL. |
554 * @param int|string $start_of_week Optional. Start of the week as an integer. Default empty string. |
576 * @param int|string $start_of_week Optional. Start of the week as an integer. Default empty string. |
555 * @return array Keys are 'start' and 'end'. |
577 * @return int[] { |
|
578 * Week start and end dates as Unix timestamps. |
|
579 * |
|
580 * @type int $start The week start date as a Unix timestamp. |
|
581 * @type int $end The week end date as a Unix timestamp. |
|
582 * } |
556 */ |
583 */ |
557 function get_weekstartend( $mysqlstring, $start_of_week = '' ) { |
584 function get_weekstartend( $mysqlstring, $start_of_week = '' ) { |
558 // MySQL string year. |
585 // MySQL string year. |
559 $my = substr( $mysqlstring, 0, 4 ); |
586 $my = substr( $mysqlstring, 0, 4 ); |
560 |
587 |
2517 |
2556 |
2518 // At this point the file name may not be unique. This is tested below and the $number is incremented. |
2557 // At this point the file name may not be unique. This is tested below and the $number is incremented. |
2519 $filename = str_replace( "{$fname}{$ext}", "{$fname}-{$number}{$ext}", $filename ); |
2558 $filename = str_replace( "{$fname}{$ext}", "{$fname}-{$number}{$ext}", $filename ); |
2520 } |
2559 } |
2521 |
2560 |
2522 // Get the mime type. Uploaded files were already checked with wp_check_filetype_and_ext() |
2561 /* |
2523 // in _wp_handle_upload(). Using wp_check_filetype() would be sufficient here. |
2562 * Get the mime type. Uploaded files were already checked with wp_check_filetype_and_ext() |
|
2563 * in _wp_handle_upload(). Using wp_check_filetype() would be sufficient here. |
|
2564 */ |
2524 $file_type = wp_check_filetype( $filename ); |
2565 $file_type = wp_check_filetype( $filename ); |
2525 $mime_type = $file_type['type']; |
2566 $mime_type = $file_type['type']; |
2526 |
2567 |
2527 $is_image = ( ! empty( $mime_type ) && 0 === strpos( $mime_type, 'image/' ) ); |
2568 $is_image = ( ! empty( $mime_type ) && 0 === strpos( $mime_type, 'image/' ) ); |
2528 $upload_dir = wp_get_upload_dir(); |
2569 $upload_dir = wp_get_upload_dir(); |
2529 $lc_filename = null; |
2570 $lc_filename = null; |
2530 |
2571 |
2531 $lc_ext = strtolower( $ext ); |
2572 $lc_ext = strtolower( $ext ); |
2532 $_dir = trailingslashit( $dir ); |
2573 $_dir = trailingslashit( $dir ); |
2533 |
2574 |
2534 // If the extension is uppercase add an alternate file name with lowercase extension. Both need to be tested |
2575 /* |
2535 // for uniqueness as the extension will be changed to lowercase for better compatibility with different filesystems. |
2576 * If the extension is uppercase add an alternate file name with lowercase extension. |
2536 // Fixes an inconsistency in WP < 2.9 where uppercase extensions were allowed but image sub-sizes were created with |
2577 * Both need to be tested for uniqueness as the extension will be changed to lowercase |
2537 // lowercase extensions. |
2578 * for better compatibility with different filesystems. Fixes an inconsistency in WP < 2.9 |
|
2579 * where uppercase extensions were allowed but image sub-sizes were created with |
|
2580 * lowercase extensions. |
|
2581 */ |
2538 if ( $ext && $lc_ext !== $ext ) { |
2582 if ( $ext && $lc_ext !== $ext ) { |
2539 $lc_filename = preg_replace( '|' . preg_quote( $ext ) . '$|', $lc_ext, $filename ); |
2583 $lc_filename = preg_replace( '|' . preg_quote( $ext ) . '$|', $lc_ext, $filename ); |
2540 } |
2584 } |
2541 |
2585 |
2542 // Increment the number added to the file name if there are any files in $dir whose names match one of the |
2586 /* |
2543 // possible name variations. |
2587 * Increment the number added to the file name if there are any files in $dir |
|
2588 * whose names match one of the possible name variations. |
|
2589 */ |
2544 while ( file_exists( $_dir . $filename ) || ( $lc_filename && file_exists( $_dir . $lc_filename ) ) ) { |
2590 while ( file_exists( $_dir . $filename ) || ( $lc_filename && file_exists( $_dir . $lc_filename ) ) ) { |
2545 $new_number = (int) $number + 1; |
2591 $new_number = (int) $number + 1; |
2546 |
2592 |
2547 if ( $lc_filename ) { |
2593 if ( $lc_filename ) { |
2548 $lc_filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $lc_filename ); |
2594 $lc_filename = str_replace( |
|
2595 array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), |
|
2596 "-{$new_number}{$lc_ext}", |
|
2597 $lc_filename |
|
2598 ); |
2549 } |
2599 } |
2550 |
2600 |
2551 if ( '' === "{$number}{$ext}" ) { |
2601 if ( '' === "{$number}{$ext}" ) { |
2552 $filename = "{$filename}-{$new_number}"; |
2602 $filename = "{$filename}-{$new_number}"; |
2553 } else { |
2603 } else { |
2554 $filename = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename ); |
2604 $filename = str_replace( |
|
2605 array( "-{$number}{$ext}", "{$number}{$ext}" ), |
|
2606 "-{$new_number}{$ext}", |
|
2607 $filename |
|
2608 ); |
2555 } |
2609 } |
2556 |
2610 |
2557 $number = $new_number; |
2611 $number = $new_number; |
2558 } |
2612 } |
2559 |
2613 |
2560 // Change the extension to lowercase if needed. |
2614 // Change the extension to lowercase if needed. |
2561 if ( $lc_filename ) { |
2615 if ( $lc_filename ) { |
2562 $filename = $lc_filename; |
2616 $filename = $lc_filename; |
2563 } |
2617 } |
2564 |
2618 |
2565 // Prevent collisions with existing file names that contain dimension-like strings |
2619 /* |
2566 // (whether they are subsizes or originals uploaded prior to #42437). |
2620 * Prevent collisions with existing file names that contain dimension-like strings |
|
2621 * (whether they are subsizes or originals uploaded prior to #42437). |
|
2622 */ |
2567 |
2623 |
2568 $files = array(); |
2624 $files = array(); |
2569 $count = 10000; |
2625 $count = 10000; |
2570 |
2626 |
2571 // The (resized) image files would have name and extension, and will be in the uploads dir. |
2627 // The (resized) image files would have name and extension, and will be in the uploads dir. |
2596 } |
2652 } |
2597 |
2653 |
2598 if ( ! empty( $files ) ) { |
2654 if ( ! empty( $files ) ) { |
2599 $count = count( $files ); |
2655 $count = count( $files ); |
2600 |
2656 |
2601 // Ensure this never goes into infinite loop |
2657 /* |
2602 // as it uses pathinfo() and regex in the check, but string replacement for the changes. |
2658 * Ensure this never goes into infinite loop as it uses pathinfo() and regex in the check, |
|
2659 * but string replacement for the changes. |
|
2660 */ |
2603 $i = 0; |
2661 $i = 0; |
2604 |
2662 |
2605 while ( $i <= $count && _wp_check_existing_file_names( $filename, $files ) ) { |
2663 while ( $i <= $count && _wp_check_existing_file_names( $filename, $files ) ) { |
2606 $new_number = (int) $number + 1; |
2664 $new_number = (int) $number + 1; |
2607 |
2665 |
2608 // If $ext is uppercase it was replaced with the lowercase version after the previous loop. |
2666 // If $ext is uppercase it was replaced with the lowercase version after the previous loop. |
2609 $filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $filename ); |
2667 $filename = str_replace( |
|
2668 array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), |
|
2669 "-{$new_number}{$lc_ext}", |
|
2670 $filename |
|
2671 ); |
2610 |
2672 |
2611 $number = $new_number; |
2673 $number = $new_number; |
2612 $i++; |
2674 $i++; |
2613 } |
2675 } |
2614 } |
2676 } |
2615 } |
2677 } |
2616 |
2678 |
2617 // Check if an image will be converted after uploading or some existing images sub-sizes file names may conflict |
2679 /* |
2618 // when regenerated. If yes, ensure the new file name will be unique and will produce unique sub-sizes. |
2680 * Check if an image will be converted after uploading or some existing image sub-size file names may conflict |
|
2681 * when regenerated. If yes, ensure the new file name will be unique and will produce unique sub-sizes. |
|
2682 */ |
2619 if ( $is_image ) { |
2683 if ( $is_image ) { |
|
2684 /** This filter is documented in wp-includes/class-wp-image-editor.php */ |
2620 $output_formats = apply_filters( 'image_editor_output_format', array(), $_dir . $filename, $mime_type ); |
2685 $output_formats = apply_filters( 'image_editor_output_format', array(), $_dir . $filename, $mime_type ); |
2621 $alt_types = array(); |
2686 $alt_types = array(); |
2622 |
2687 |
2623 if ( ! empty( $output_formats[ $mime_type ] ) ) { |
2688 if ( ! empty( $output_formats[ $mime_type ] ) ) { |
2624 // The image will be converted to this format/mime type. |
2689 // The image will be converted to this format/mime type. |
2646 |
2711 |
2647 $alt_filenames[ $alt_ext ] = $alt_filename; |
2712 $alt_filenames[ $alt_ext ] = $alt_filename; |
2648 } |
2713 } |
2649 |
2714 |
2650 if ( ! empty( $alt_filenames ) ) { |
2715 if ( ! empty( $alt_filenames ) ) { |
2651 // Add the original filename. It needs to be checked again together with the alternate filenames |
2716 /* |
2652 // when $number is incremented. |
2717 * Add the original filename. It needs to be checked again |
|
2718 * together with the alternate filenames when $number is incremented. |
|
2719 */ |
2653 $alt_filenames[ $lc_ext ] = $filename; |
2720 $alt_filenames[ $lc_ext ] = $filename; |
2654 |
2721 |
2655 // Ensure no infinite loop. |
2722 // Ensure no infinite loop. |
2656 $i = 0; |
2723 $i = 0; |
2657 |
2724 |
2658 while ( $i <= $count && _wp_check_alternate_file_names( $alt_filenames, $_dir, $files ) ) { |
2725 while ( $i <= $count && _wp_check_alternate_file_names( $alt_filenames, $_dir, $files ) ) { |
2659 $new_number = (int) $number + 1; |
2726 $new_number = (int) $number + 1; |
2660 |
2727 |
2661 foreach ( $alt_filenames as $alt_ext => $alt_filename ) { |
2728 foreach ( $alt_filenames as $alt_ext => $alt_filename ) { |
2662 $alt_filenames[ $alt_ext ] = str_replace( array( "-{$number}{$alt_ext}", "{$number}{$alt_ext}" ), "-{$new_number}{$alt_ext}", $alt_filename ); |
2729 $alt_filenames[ $alt_ext ] = str_replace( |
|
2730 array( "-{$number}{$alt_ext}", "{$number}{$alt_ext}" ), |
|
2731 "-{$new_number}{$alt_ext}", |
|
2732 $alt_filename |
|
2733 ); |
2663 } |
2734 } |
2664 |
2735 |
2665 // Also update the $number in (the output) $filename. |
2736 /* |
2666 // If the extension was uppercase it was already replaced with the lowercase version. |
2737 * Also update the $number in (the output) $filename. |
2667 $filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $filename ); |
2738 * If the extension was uppercase it was already replaced with the lowercase version. |
|
2739 */ |
|
2740 $filename = str_replace( |
|
2741 array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), |
|
2742 "-{$new_number}{$lc_ext}", |
|
2743 $filename |
|
2744 ); |
2668 |
2745 |
2669 $number = $new_number; |
2746 $number = $new_number; |
2670 $i++; |
2747 $i++; |
2671 } |
2748 } |
2672 } |
2749 } |
2678 * |
2755 * |
2679 * @since 4.5.0 |
2756 * @since 4.5.0 |
2680 * @since 5.8.1 The `$alt_filenames` and `$number` parameters were added. |
2757 * @since 5.8.1 The `$alt_filenames` and `$number` parameters were added. |
2681 * |
2758 * |
2682 * @param string $filename Unique file name. |
2759 * @param string $filename Unique file name. |
2683 * @param string $ext File extension, eg. ".png". |
2760 * @param string $ext File extension. Example: ".png". |
2684 * @param string $dir Directory path. |
2761 * @param string $dir Directory path. |
2685 * @param callable|null $unique_filename_callback Callback function that generates the unique file name. |
2762 * @param callable|null $unique_filename_callback Callback function that generates the unique file name. |
2686 * @param string[] $alt_filenames Array of alternate file names that were checked for collisions. |
2763 * @param string[] $alt_filenames Array of alternate file names that were checked for collisions. |
2687 * @param int|string $number The highest number that was used to make the file name unique |
2764 * @param int|string $number The highest number that was used to make the file name unique |
2688 * or an empty string if unused. |
2765 * or an empty string if unused. |
3406 ) |
3477 ) |
3407 ); |
3478 ); |
3408 } |
3479 } |
3409 |
3480 |
3410 /** |
3481 /** |
|
3482 * Wrapper for PHP filesize with filters and casting the result as an integer. |
|
3483 * |
|
3484 * @since 6.0.0 |
|
3485 * |
|
3486 * @link https://www.php.net/manual/en/function.filesize.php |
|
3487 * |
|
3488 * @param string $path Path to the file. |
|
3489 * @return int The size of the file in bytes, or 0 in the event of an error. |
|
3490 */ |
|
3491 function wp_filesize( $path ) { |
|
3492 /** |
|
3493 * Filters the result of wp_filesize before the PHP function is run. |
|
3494 * |
|
3495 * @since 6.0.0 |
|
3496 * |
|
3497 * @param null|int $size The unfiltered value. Returning an int from the callback bypasses the filesize call. |
|
3498 * @param string $path Path to the file. |
|
3499 */ |
|
3500 $size = apply_filters( 'pre_wp_filesize', null, $path ); |
|
3501 |
|
3502 if ( is_int( $size ) ) { |
|
3503 return $size; |
|
3504 } |
|
3505 |
|
3506 $size = file_exists( $path ) ? (int) filesize( $path ) : 0; |
|
3507 |
|
3508 /** |
|
3509 * Filters the size of the file. |
|
3510 * |
|
3511 * @since 6.0.0 |
|
3512 * |
|
3513 * @param int $size The result of PHP filesize on the file. |
|
3514 * @param string $path Path to the file. |
|
3515 */ |
|
3516 return (int) apply_filters( 'wp_filesize', $size, $path ); |
|
3517 } |
|
3518 |
|
3519 /** |
3411 * Retrieve list of allowed mime types and file extensions. |
3520 * Retrieve list of allowed mime types and file extensions. |
3412 * |
3521 * |
3413 * @since 2.8.6 |
3522 * @since 2.8.6 |
3414 * |
3523 * |
3415 * @param int|WP_User $user Optional. User to check. Defaults to current user. |
3524 * @param int|WP_User $user Optional. User to check. Defaults to current user. |
3448 * @since 2.0.4 |
3557 * @since 2.0.4 |
3449 * |
3558 * |
3450 * @param string $action The nonce action. |
3559 * @param string $action The nonce action. |
3451 */ |
3560 */ |
3452 function wp_nonce_ays( $action ) { |
3561 function wp_nonce_ays( $action ) { |
|
3562 // Default title and response code. |
|
3563 $title = __( 'Something went wrong.' ); |
|
3564 $response_code = 403; |
|
3565 |
3453 if ( 'log-out' === $action ) { |
3566 if ( 'log-out' === $action ) { |
3454 $html = sprintf( |
3567 $title = sprintf( |
3455 /* translators: %s: Site title. */ |
3568 /* translators: %s: Site title. */ |
3456 __( 'You are attempting to log out of %s' ), |
3569 __( 'You are attempting to log out of %s' ), |
3457 get_bloginfo( 'name' ) |
3570 get_bloginfo( 'name' ) |
3458 ); |
3571 ); |
|
3572 $html = $title; |
3459 $html .= '</p><p>'; |
3573 $html .= '</p><p>'; |
3460 $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : ''; |
3574 $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : ''; |
3461 $html .= sprintf( |
3575 $html .= sprintf( |
3462 /* translators: %s: Logout URL. */ |
3576 /* translators: %s: Logout URL. */ |
3463 __( 'Do you really want to <a href="%s">log out</a>?' ), |
3577 __( 'Do you really want to <a href="%s">log out</a>?' ), |
3540 /** |
3654 /** |
3541 * Filters the callback for killing WordPress execution for Ajax requests. |
3655 * Filters the callback for killing WordPress execution for Ajax requests. |
3542 * |
3656 * |
3543 * @since 3.4.0 |
3657 * @since 3.4.0 |
3544 * |
3658 * |
3545 * @param callable $function Callback function name. |
3659 * @param callable $callback Callback function name. |
3546 */ |
3660 */ |
3547 $function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' ); |
3661 $callback = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' ); |
3548 } elseif ( wp_is_json_request() ) { |
3662 } elseif ( wp_is_json_request() ) { |
3549 /** |
3663 /** |
3550 * Filters the callback for killing WordPress execution for JSON requests. |
3664 * Filters the callback for killing WordPress execution for JSON requests. |
3551 * |
3665 * |
3552 * @since 5.1.0 |
3666 * @since 5.1.0 |
3553 * |
3667 * |
3554 * @param callable $function Callback function name. |
3668 * @param callable $callback Callback function name. |
3555 */ |
3669 */ |
3556 $function = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' ); |
3670 $callback = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' ); |
3557 } elseif ( defined( 'REST_REQUEST' ) && REST_REQUEST && wp_is_jsonp_request() ) { |
3671 } elseif ( defined( 'REST_REQUEST' ) && REST_REQUEST && wp_is_jsonp_request() ) { |
3558 /** |
3672 /** |
3559 * Filters the callback for killing WordPress execution for JSONP REST requests. |
3673 * Filters the callback for killing WordPress execution for JSONP REST requests. |
3560 * |
3674 * |
3561 * @since 5.2.0 |
3675 * @since 5.2.0 |
3562 * |
3676 * |
3563 * @param callable $function Callback function name. |
3677 * @param callable $callback Callback function name. |
3564 */ |
3678 */ |
3565 $function = apply_filters( 'wp_die_jsonp_handler', '_jsonp_wp_die_handler' ); |
3679 $callback = apply_filters( 'wp_die_jsonp_handler', '_jsonp_wp_die_handler' ); |
3566 } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { |
3680 } elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { |
3567 /** |
3681 /** |
3568 * Filters the callback for killing WordPress execution for XML-RPC requests. |
3682 * Filters the callback for killing WordPress execution for XML-RPC requests. |
3569 * |
3683 * |
3570 * @since 3.4.0 |
3684 * @since 3.4.0 |
3571 * |
3685 * |
3572 * @param callable $function Callback function name. |
3686 * @param callable $callback Callback function name. |
3573 */ |
3687 */ |
3574 $function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' ); |
3688 $callback = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' ); |
3575 } elseif ( wp_is_xml_request() |
3689 } elseif ( wp_is_xml_request() |
3576 || isset( $wp_query ) && |
3690 || isset( $wp_query ) && |
3577 ( function_exists( 'is_feed' ) && is_feed() |
3691 ( function_exists( 'is_feed' ) && is_feed() |
3578 || function_exists( 'is_comment_feed' ) && is_comment_feed() |
3692 || function_exists( 'is_comment_feed' ) && is_comment_feed() |
3579 || function_exists( 'is_trackback' ) && is_trackback() ) ) { |
3693 || function_exists( 'is_trackback' ) && is_trackback() ) ) { |
3580 /** |
3694 /** |
3581 * Filters the callback for killing WordPress execution for XML requests. |
3695 * Filters the callback for killing WordPress execution for XML requests. |
3582 * |
3696 * |
3583 * @since 5.2.0 |
3697 * @since 5.2.0 |
3584 * |
3698 * |
3585 * @param callable $function Callback function name. |
3699 * @param callable $callback Callback function name. |
3586 */ |
3700 */ |
3587 $function = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' ); |
3701 $callback = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' ); |
3588 } else { |
3702 } else { |
3589 /** |
3703 /** |
3590 * Filters the callback for killing WordPress execution for all non-Ajax, non-JSON, non-XML requests. |
3704 * Filters the callback for killing WordPress execution for all non-Ajax, non-JSON, non-XML requests. |
3591 * |
3705 * |
3592 * @since 3.0.0 |
3706 * @since 3.0.0 |
3593 * |
3707 * |
3594 * @param callable $function Callback function name. |
3708 * @param callable $callback Callback function name. |
3595 */ |
3709 */ |
3596 $function = apply_filters( 'wp_die_handler', '_default_wp_die_handler' ); |
3710 $callback = apply_filters( 'wp_die_handler', '_default_wp_die_handler' ); |
3597 } |
3711 } |
3598 |
3712 |
3599 call_user_func( $function, $message, $title, $args ); |
3713 call_user_func( $callback, $message, $title, $args ); |
3600 } |
3714 } |
3601 |
3715 |
3602 /** |
3716 /** |
3603 * Kills WordPress execution and displays HTML page with an error message. |
3717 * Kills WordPress execution and displays HTML page with an error message. |
3604 * |
3718 * |
4391 |
4505 |
4392 return 0 === $illegal_char_count; |
4506 return 0 === $illegal_char_count; |
4393 } |
4507 } |
4394 |
4508 |
4395 /** |
4509 /** |
|
4510 * Reads and decodes a JSON file. |
|
4511 * |
|
4512 * @since 5.9.0 |
|
4513 * |
|
4514 * @param string $filename Path to the JSON file. |
|
4515 * @param array $options { |
|
4516 * Optional. Options to be used with `json_decode()`. |
|
4517 * |
|
4518 * @type bool $associative Optional. When `true`, JSON objects will be returned as associative arrays. |
|
4519 * When `false`, JSON objects will be returned as objects. |
|
4520 * } |
|
4521 * |
|
4522 * @return mixed Returns the value encoded in JSON in appropriate PHP type. |
|
4523 * `null` is returned if the file is not found, or its content can't be decoded. |
|
4524 */ |
|
4525 function wp_json_file_decode( $filename, $options = array() ) { |
|
4526 $result = null; |
|
4527 $filename = wp_normalize_path( realpath( $filename ) ); |
|
4528 if ( ! file_exists( $filename ) ) { |
|
4529 trigger_error( |
|
4530 sprintf( |
|
4531 /* translators: %s: Path to the JSON file. */ |
|
4532 __( "File %s doesn't exist!" ), |
|
4533 $filename |
|
4534 ) |
|
4535 ); |
|
4536 return $result; |
|
4537 } |
|
4538 |
|
4539 $options = wp_parse_args( $options, array( 'associative' => false ) ); |
|
4540 $decoded_file = json_decode( file_get_contents( $filename ), $options['associative'] ); |
|
4541 |
|
4542 if ( JSON_ERROR_NONE !== json_last_error() ) { |
|
4543 trigger_error( |
|
4544 sprintf( |
|
4545 /* translators: 1: Path to the JSON file, 2: Error message. */ |
|
4546 __( 'Error when decoding a JSON file at path %1$s: %2$s' ), |
|
4547 $filename, |
|
4548 json_last_error_msg() |
|
4549 ) |
|
4550 ); |
|
4551 return $result; |
|
4552 } |
|
4553 |
|
4554 return $decoded_file; |
|
4555 } |
|
4556 |
|
4557 /** |
4396 * Retrieve the WordPress home page URL. |
4558 * Retrieve the WordPress home page URL. |
4397 * |
4559 * |
4398 * If the constant named 'WP_HOME' exists, then it will be used and returned |
4560 * If the constant named 'WP_HOME' exists, then it will be used and returned |
4399 * by the function. This can be used to counter the redirection on your local |
4561 * by the function. This can be used to counter the redirection on your local |
4400 * development environment. |
4562 * development environment. |
4978 * If you want to retrieve a particular field from all matching objects, |
5140 * If you want to retrieve a particular field from all matching objects, |
4979 * use wp_filter_object_list() instead. |
5141 * use wp_filter_object_list() instead. |
4980 * |
5142 * |
4981 * @since 3.1.0 |
5143 * @since 3.1.0 |
4982 * @since 4.7.0 Uses `WP_List_Util` class. |
5144 * @since 4.7.0 Uses `WP_List_Util` class. |
|
5145 * @since 5.9.0 Converted into a wrapper for `wp_filter_object_list()`. |
4983 * |
5146 * |
4984 * @param array $list An array of objects to filter. |
5147 * @param array $list An array of objects to filter. |
4985 * @param array $args Optional. An array of key => value arguments to match |
5148 * @param array $args Optional. An array of key => value arguments to match |
4986 * against each object. Default empty array. |
5149 * against each object. Default empty array. |
4987 * @param string $operator Optional. The logical operation to perform. 'AND' means |
5150 * @param string $operator Optional. The logical operation to perform. 'AND' means |
4989 * one element needs to match. 'NOT' means no elements may |
5152 * one element needs to match. 'NOT' means no elements may |
4990 * match. Default 'AND'. |
5153 * match. Default 'AND'. |
4991 * @return array Array of found values. |
5154 * @return array Array of found values. |
4992 */ |
5155 */ |
4993 function wp_list_filter( $list, $args = array(), $operator = 'AND' ) { |
5156 function wp_list_filter( $list, $args = array(), $operator = 'AND' ) { |
4994 if ( ! is_array( $list ) ) { |
5157 return wp_filter_object_list( $list, $args, $operator ); |
4995 return array(); |
5158 } |
4996 } |
5159 |
4997 |
5160 /** |
4998 $util = new WP_List_Util( $list ); |
5161 * Plucks a certain field out of each object or array in an array. |
4999 |
|
5000 return $util->filter( $args, $operator ); |
|
5001 } |
|
5002 |
|
5003 /** |
|
5004 * Pluck a certain field out of each object in a list. |
|
5005 * |
5162 * |
5006 * This has the same functionality and prototype of |
5163 * This has the same functionality and prototype of |
5007 * array_column() (PHP 5.5) but also supports objects. |
5164 * array_column() (PHP 5.5) but also supports objects. |
5008 * |
5165 * |
5009 * @since 3.1.0 |
5166 * @since 3.1.0 |
5017 * @return array Array of found values. If `$index_key` is set, an array of found values with keys |
5174 * @return array Array of found values. If `$index_key` is set, an array of found values with keys |
5018 * corresponding to `$index_key`. If `$index_key` is null, array keys from the original |
5175 * corresponding to `$index_key`. If `$index_key` is null, array keys from the original |
5019 * `$list` will be preserved in the results. |
5176 * `$list` will be preserved in the results. |
5020 */ |
5177 */ |
5021 function wp_list_pluck( $list, $field, $index_key = null ) { |
5178 function wp_list_pluck( $list, $field, $index_key = null ) { |
|
5179 if ( ! is_array( $list ) ) { |
|
5180 return array(); |
|
5181 } |
|
5182 |
5022 $util = new WP_List_Util( $list ); |
5183 $util = new WP_List_Util( $list ); |
5023 |
5184 |
5024 return $util->pluck( $field, $index_key ); |
5185 return $util->pluck( $field, $index_key ); |
5025 } |
5186 } |
5026 |
5187 |
5027 /** |
5188 /** |
5028 * Sorts a list of objects, based on one or more orderby arguments. |
5189 * Sorts an array of objects or arrays based on one or more orderby arguments. |
5029 * |
5190 * |
5030 * @since 4.7.0 |
5191 * @since 4.7.0 |
5031 * |
5192 * |
5032 * @param array $list An array of objects to sort. |
5193 * @param array $list An array of objects to sort. |
5033 * @param string|array $orderby Optional. Either the field name to order by or an array |
5194 * @param string|array $orderby Optional. Either the field name to order by or an array |
5078 |
5239 |
5079 /** |
5240 /** |
5080 * Append the Widgets menu to the themes main menu. |
5241 * Append the Widgets menu to the themes main menu. |
5081 * |
5242 * |
5082 * @since 2.2.0 |
5243 * @since 2.2.0 |
|
5244 * @since 5.9.3 Don't specify menu order when the active theme is a block theme. |
5083 * |
5245 * |
5084 * @global array $submenu |
5246 * @global array $submenu |
5085 */ |
5247 */ |
5086 function wp_widgets_add_menu() { |
5248 function wp_widgets_add_menu() { |
5087 global $submenu; |
5249 global $submenu; |
5088 |
5250 |
5089 if ( ! current_theme_supports( 'widgets' ) ) { |
5251 if ( ! current_theme_supports( 'widgets' ) ) { |
5090 return; |
5252 return; |
5091 } |
5253 } |
5092 |
5254 |
5093 $submenu['themes.php'][7] = array( __( 'Widgets' ), 'edit_theme_options', 'widgets.php' ); |
5255 $menu_name = __( 'Widgets' ); |
|
5256 if ( wp_is_block_theme() ) { |
|
5257 $submenu['themes.php'][] = array( $menu_name, 'edit_theme_options', 'widgets.php' ); |
|
5258 } else { |
|
5259 $submenu['themes.php'][7] = array( $menu_name, 'edit_theme_options', 'widgets.php' ); |
|
5260 } |
|
5261 |
5094 ksort( $submenu['themes.php'], SORT_NUMERIC ); |
5262 ksort( $submenu['themes.php'], SORT_NUMERIC ); |
5095 } |
5263 } |
5096 |
5264 |
5097 /** |
5265 /** |
5098 * Flush all output buffers for PHP 5.2. |
5266 * Flush all output buffers for PHP 5.2. |
5201 if ( function_exists( '__' ) ) { |
5369 if ( function_exists( '__' ) ) { |
5202 if ( $replacement ) { |
5370 if ( $replacement ) { |
5203 trigger_error( |
5371 trigger_error( |
5204 sprintf( |
5372 sprintf( |
5205 /* translators: 1: PHP function name, 2: Version number, 3: Alternative function name. */ |
5373 /* translators: 1: PHP function name, 2: Version number, 3: Alternative function name. */ |
5206 __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), |
5374 __( 'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), |
5207 $function, |
5375 $function, |
5208 $version, |
5376 $version, |
5209 $replacement |
5377 $replacement |
5210 ), |
5378 ), |
5211 E_USER_DEPRECATED |
5379 E_USER_DEPRECATED |
5212 ); |
5380 ); |
5213 } else { |
5381 } else { |
5214 trigger_error( |
5382 trigger_error( |
5215 sprintf( |
5383 sprintf( |
5216 /* translators: 1: PHP function name, 2: Version number. */ |
5384 /* translators: 1: PHP function name, 2: Version number. */ |
5217 __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), |
5385 __( 'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), |
5218 $function, |
5386 $function, |
5219 $version |
5387 $version |
5220 ), |
5388 ), |
5221 E_USER_DEPRECATED |
5389 E_USER_DEPRECATED |
5222 ); |
5390 ); |
5223 } |
5391 } |
5224 } else { |
5392 } else { |
5225 if ( $replacement ) { |
5393 if ( $replacement ) { |
5226 trigger_error( |
5394 trigger_error( |
5227 sprintf( |
5395 sprintf( |
5228 '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', |
5396 'Function %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', |
5229 $function, |
5397 $function, |
5230 $version, |
5398 $version, |
5231 $replacement |
5399 $replacement |
5232 ), |
5400 ), |
5233 E_USER_DEPRECATED |
5401 E_USER_DEPRECATED |
5234 ); |
5402 ); |
5235 } else { |
5403 } else { |
5236 trigger_error( |
5404 trigger_error( |
5237 sprintf( |
5405 sprintf( |
5238 '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', |
5406 'Function %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', |
5239 $function, |
5407 $function, |
5240 $version |
5408 $version |
5241 ), |
5409 ), |
5242 E_USER_DEPRECATED |
5410 E_USER_DEPRECATED |
5243 ); |
5411 ); |
5391 if ( function_exists( '__' ) ) { |
5559 if ( function_exists( '__' ) ) { |
5392 if ( $replacement ) { |
5560 if ( $replacement ) { |
5393 trigger_error( |
5561 trigger_error( |
5394 sprintf( |
5562 sprintf( |
5395 /* translators: 1: PHP file name, 2: Version number, 3: Alternative file name. */ |
5563 /* translators: 1: PHP file name, 2: Version number, 3: Alternative file name. */ |
5396 __( '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), |
5564 __( 'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.' ), |
5397 $file, |
5565 $file, |
5398 $version, |
5566 $version, |
5399 $replacement |
5567 $replacement |
5400 ) . $message, |
5568 ) . $message, |
5401 E_USER_DEPRECATED |
5569 E_USER_DEPRECATED |
5402 ); |
5570 ); |
5403 } else { |
5571 } else { |
5404 trigger_error( |
5572 trigger_error( |
5405 sprintf( |
5573 sprintf( |
5406 /* translators: 1: PHP file name, 2: Version number. */ |
5574 /* translators: 1: PHP file name, 2: Version number. */ |
5407 __( '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), |
5575 __( 'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.' ), |
5408 $file, |
5576 $file, |
5409 $version |
5577 $version |
5410 ) . $message, |
5578 ) . $message, |
5411 E_USER_DEPRECATED |
5579 E_USER_DEPRECATED |
5412 ); |
5580 ); |
5413 } |
5581 } |
5414 } else { |
5582 } else { |
5415 if ( $replacement ) { |
5583 if ( $replacement ) { |
5416 trigger_error( |
5584 trigger_error( |
5417 sprintf( |
5585 sprintf( |
5418 '%1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', |
5586 'File %1$s is <strong>deprecated</strong> since version %2$s! Use %3$s instead.', |
5419 $file, |
5587 $file, |
5420 $version, |
5588 $version, |
5421 $replacement |
5589 $replacement |
5422 ) . $message, |
5590 ) . $message, |
5423 E_USER_DEPRECATED |
5591 E_USER_DEPRECATED |
5424 ); |
5592 ); |
5425 } else { |
5593 } else { |
5426 trigger_error( |
5594 trigger_error( |
5427 sprintf( |
5595 sprintf( |
5428 '%1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', |
5596 'File %1$s is <strong>deprecated</strong> since version %2$s with no alternative available.', |
5429 $file, |
5597 $file, |
5430 $version |
5598 $version |
5431 ) . $message, |
5599 ) . $message, |
5432 E_USER_DEPRECATED |
5600 E_USER_DEPRECATED |
5433 ); |
5601 ); |
5485 if ( function_exists( '__' ) ) { |
5653 if ( function_exists( '__' ) ) { |
5486 if ( $message ) { |
5654 if ( $message ) { |
5487 trigger_error( |
5655 trigger_error( |
5488 sprintf( |
5656 sprintf( |
5489 /* translators: 1: PHP function name, 2: Version number, 3: Optional message regarding the change. */ |
5657 /* translators: 1: PHP function name, 2: Version number, 3: Optional message regarding the change. */ |
5490 __( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ), |
5658 __( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s' ), |
5491 $function, |
5659 $function, |
5492 $version, |
5660 $version, |
5493 $message |
5661 $message |
5494 ), |
5662 ), |
5495 E_USER_DEPRECATED |
5663 E_USER_DEPRECATED |
5496 ); |
5664 ); |
5497 } else { |
5665 } else { |
5498 trigger_error( |
5666 trigger_error( |
5499 sprintf( |
5667 sprintf( |
5500 /* translators: 1: PHP function name, 2: Version number. */ |
5668 /* translators: 1: PHP function name, 2: Version number. */ |
5501 __( '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ), |
5669 __( 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.' ), |
5502 $function, |
5670 $function, |
5503 $version |
5671 $version |
5504 ), |
5672 ), |
5505 E_USER_DEPRECATED |
5673 E_USER_DEPRECATED |
5506 ); |
5674 ); |
5507 } |
5675 } |
5508 } else { |
5676 } else { |
5509 if ( $message ) { |
5677 if ( $message ) { |
5510 trigger_error( |
5678 trigger_error( |
5511 sprintf( |
5679 sprintf( |
5512 '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s', |
5680 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s! %3$s', |
5513 $function, |
5681 $function, |
5514 $version, |
5682 $version, |
5515 $message |
5683 $message |
5516 ), |
5684 ), |
5517 E_USER_DEPRECATED |
5685 E_USER_DEPRECATED |
5518 ); |
5686 ); |
5519 } else { |
5687 } else { |
5520 trigger_error( |
5688 trigger_error( |
5521 sprintf( |
5689 sprintf( |
5522 '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.', |
5690 'Function %1$s was called with an argument that is <strong>deprecated</strong> since version %2$s with no alternative available.', |
5523 $function, |
5691 $function, |
5524 $version |
5692 $version |
5525 ), |
5693 ), |
5526 E_USER_DEPRECATED |
5694 E_USER_DEPRECATED |
5527 ); |
5695 ); |
5784 * @param string $file File path. |
5952 * @param string $file File path. |
5785 * @param string[] $allowed_files Optional. Array of allowed files. |
5953 * @param string[] $allowed_files Optional. Array of allowed files. |
5786 * @return int 0 means nothing is wrong, greater than 0 means something was wrong. |
5954 * @return int 0 means nothing is wrong, greater than 0 means something was wrong. |
5787 */ |
5955 */ |
5788 function validate_file( $file, $allowed_files = array() ) { |
5956 function validate_file( $file, $allowed_files = array() ) { |
|
5957 if ( ! is_scalar( $file ) || '' === $file ) { |
|
5958 return 0; |
|
5959 } |
|
5960 |
5789 // `../` on its own is not allowed: |
5961 // `../` on its own is not allowed: |
5790 if ( '../' === $file ) { |
5962 if ( '../' === $file ) { |
5791 return 1; |
5963 return 1; |
5792 } |
5964 } |
5793 |
5965 |
5794 // More than one occurence of `../` is not allowed: |
5966 // More than one occurrence of `../` is not allowed: |
5795 if ( preg_match_all( '#\.\./#', $file, $matches, PREG_SET_ORDER ) && ( count( $matches ) > 1 ) ) { |
5967 if ( preg_match_all( '#\.\./#', $file, $matches, PREG_SET_ORDER ) && ( count( $matches ) > 1 ) ) { |
5796 return 1; |
5968 return 1; |
5797 } |
5969 } |
5798 |
5970 |
5799 // `../` which does not occur at the end of the path is not allowed: |
5971 // `../` which does not occur at the end of the path is not allowed: |
6455 * @param string $context Optional. If specified adds filter hook {@see 'extra_$context_headers'}. |
6627 * @param string $context Optional. If specified adds filter hook {@see 'extra_$context_headers'}. |
6456 * Default empty. |
6628 * Default empty. |
6457 * @return string[] Array of file header values keyed by header name. |
6629 * @return string[] Array of file header values keyed by header name. |
6458 */ |
6630 */ |
6459 function get_file_data( $file, $default_headers, $context = '' ) { |
6631 function get_file_data( $file, $default_headers, $context = '' ) { |
6460 // We don't need to write to the file, so just open for reading. |
6632 // Pull only the first 8 KB of the file in. |
6461 $fp = fopen( $file, 'r' ); |
6633 $file_data = file_get_contents( $file, false, null, 0, 8 * KB_IN_BYTES ); |
6462 |
6634 |
6463 if ( $fp ) { |
6635 if ( false === $file_data ) { |
6464 // Pull only the first 8 KB of the file in. |
|
6465 $file_data = fread( $fp, 8 * KB_IN_BYTES ); |
|
6466 |
|
6467 // PHP will close file handle, but we are good citizens. |
|
6468 fclose( $fp ); |
|
6469 } else { |
|
6470 $file_data = ''; |
6636 $file_data = ''; |
6471 } |
6637 } |
6472 |
6638 |
6473 // Make sure we catch CR-only line endings. |
6639 // Make sure we catch CR-only line endings. |
6474 $file_data = str_replace( "\r", "\n", $file_data ); |
6640 $file_data = str_replace( "\r", "\n", $file_data ); |
6750 |
6916 |
6751 return $protocols; |
6917 return $protocols; |
6752 } |
6918 } |
6753 |
6919 |
6754 /** |
6920 /** |
6755 * Return a comma-separated string of functions that have been called to get |
6921 * Returns a comma-separated string or array of functions that have been called to get |
6756 * to the current point in code. |
6922 * to the current point in code. |
6757 * |
6923 * |
6758 * @since 3.4.0 |
6924 * @since 3.4.0 |
6759 * |
6925 * |
6760 * @see https://core.trac.wordpress.org/ticket/19589 |
6926 * @see https://core.trac.wordpress.org/ticket/19589 |
6761 * |
6927 * |
6762 * @param string $ignore_class Optional. A class to ignore all function calls within - useful |
6928 * @param string $ignore_class Optional. A class to ignore all function calls within - useful |
6763 * when you want to just give info about the callee. Default null. |
6929 * when you want to just give info about the callee. Default null. |
6764 * @param int $skip_frames Optional. A number of stack frames to skip - useful for unwinding |
6930 * @param int $skip_frames Optional. A number of stack frames to skip - useful for unwinding |
6765 * back to the source of the issue. Default 0. |
6931 * back to the source of the issue. Default 0. |
6766 * @param bool $pretty Optional. Whether or not you want a comma separated string or raw |
6932 * @param bool $pretty Optional. Whether you want a comma separated string instead of |
6767 * array returned. Default true. |
6933 * the raw array returned. Default true. |
6768 * @return string|array Either a string containing a reversed comma separated trace or an array |
6934 * @return string|array Either a string containing a reversed comma separated trace or an array |
6769 * of individual calls. |
6935 * of individual calls. |
6770 */ |
6936 */ |
6771 function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) { |
6937 function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) { |
6772 static $truncate_paths; |
6938 static $truncate_paths; |
7561 * @param bool $ipv6_fallback Optional. Whether to return the original IPv6 address if the needed functions |
7727 * @param bool $ipv6_fallback Optional. Whether to return the original IPv6 address if the needed functions |
7562 * to anonymize it are not present. Default false, return `::` (unspecified address). |
7728 * to anonymize it are not present. Default false, return `::` (unspecified address). |
7563 * @return string The anonymized IP address. |
7729 * @return string The anonymized IP address. |
7564 */ |
7730 */ |
7565 function wp_privacy_anonymize_ip( $ip_addr, $ipv6_fallback = false ) { |
7731 function wp_privacy_anonymize_ip( $ip_addr, $ipv6_fallback = false ) { |
|
7732 if ( empty( $ip_addr ) ) { |
|
7733 return '0.0.0.0'; |
|
7734 } |
|
7735 |
7566 // Detect what kind of IP address this is. |
7736 // Detect what kind of IP address this is. |
7567 $ip_prefix = ''; |
7737 $ip_prefix = ''; |
7568 $is_ipv6 = substr_count( $ip_addr, ':' ) > 1; |
7738 $is_ipv6 = substr_count( $ip_addr, ':' ) > 1; |
7569 $is_ipv4 = ( 3 === substr_count( $ip_addr, '.' ) ); |
7739 $is_ipv4 = ( 3 === substr_count( $ip_addr, '.' ) ); |
7570 |
7740 |
8056 * @since MU (3.0.0) |
8226 * @since MU (3.0.0) |
8057 * @since 4.3.0 The `$exclude` parameter was added. |
8227 * @since 4.3.0 The `$exclude` parameter was added. |
8058 * @since 5.2.0 The `$max_execution_time` parameter was added. |
8228 * @since 5.2.0 The `$max_execution_time` parameter was added. |
8059 * @since 5.6.0 The `$directory_cache` parameter was added. |
8229 * @since 5.6.0 The `$directory_cache` parameter was added. |
8060 * |
8230 * |
8061 * @param string $directory Full path of a directory. |
8231 * @param string $directory Full path of a directory. |
8062 * @param string|array $exclude Optional. Full path of a subdirectory to exclude from the total, |
8232 * @param string|string[] $exclude Optional. Full path of a subdirectory to exclude from the total, |
8063 * or array of paths. Expected without trailing slash(es). |
8233 * or array of paths. Expected without trailing slash(es). |
8064 * @param int $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global |
8234 * @param int $max_execution_time Optional. Maximum time to run before giving up. In seconds. |
8065 * and is measured from the moment WordPress started to load. |
8235 * The timeout is global and is measured from the moment |
8066 * @param array $directory_cache Optional. Array of cached directory paths. |
8236 * WordPress started to load. |
|
8237 * @param array $directory_cache Optional. Array of cached directory paths. |
8067 * |
8238 * |
8068 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. |
8239 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. |
8069 */ |
8240 */ |
8070 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) { |
8241 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) { |
8071 $directory = untrailingslashit( $directory ); |
8242 $directory = untrailingslashit( $directory ); |
8112 * Return the actual used space to short-circuit the recursive PHP file size calculation |
8283 * Return the actual used space to short-circuit the recursive PHP file size calculation |
8113 * and use something else, like a CDN API or native operating system tools for better performance. |
8284 * and use something else, like a CDN API or native operating system tools for better performance. |
8114 * |
8285 * |
8115 * @since 5.6.0 |
8286 * @since 5.6.0 |
8116 * |
8287 * |
8117 * @param int|false $space_used The amount of used space, in bytes. Default false. |
8288 * @param int|false $space_used The amount of used space, in bytes. Default false. |
|
8289 * @param string $directory Full path of a directory. |
|
8290 * @param string|string[]|null $exclude Full path of a subdirectory to exclude from the total, |
|
8291 * or array of paths. |
|
8292 * @param int $max_execution_time Maximum time to run before giving up. In seconds. |
|
8293 * @param array $directory_cache Array of cached directory paths. |
8118 */ |
8294 */ |
8119 $size = apply_filters( 'pre_recurse_dirsize', false, $directory, $exclude, $max_execution_time, $directory_cache ); |
8295 $size = apply_filters( 'pre_recurse_dirsize', false, $directory, $exclude, $max_execution_time, $directory_cache ); |
8120 |
8296 |
8121 if ( false === $size ) { |
8297 if ( false === $size ) { |
8122 $size = 0; |
8298 $size = 0; |
8133 if ( $handlesize > 0 ) { |
8309 if ( $handlesize > 0 ) { |
8134 $size += $handlesize; |
8310 $size += $handlesize; |
8135 } |
8311 } |
8136 } |
8312 } |
8137 |
8313 |
8138 if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) { |
8314 if ( $max_execution_time > 0 && |
|
8315 ( microtime( true ) - WP_START_TIMESTAMP ) > $max_execution_time |
|
8316 ) { |
8139 // Time exceeded. Give up instead of risking a fatal timeout. |
8317 // Time exceeded. Give up instead of risking a fatal timeout. |
8140 $size = null; |
8318 $size = null; |
8141 break; |
8319 break; |
8142 } |
8320 } |
8143 } |
8321 } |
8144 } |
8322 } |
8145 closedir( $handle ); |
8323 closedir( $handle ); |
8146 } |
8324 } |
8147 } |
8325 } |
8148 |
8326 |
|
8327 if ( ! is_array( $directory_cache ) ) { |
|
8328 $directory_cache = array(); |
|
8329 } |
|
8330 |
8149 $directory_cache[ $directory ] = $size; |
8331 $directory_cache[ $directory ] = $size; |
8150 |
8332 |
8151 // Only write the transient on the top level call and not on recursive calls. |
8333 // Only write the transient on the top level call and not on recursive calls. |
8152 if ( $save_cache ) { |
8334 if ( $save_cache ) { |
8153 set_transient( 'dirsize_cache', $directory_cache ); |
8335 set_transient( 'dirsize_cache', $directory_cache ); |
8160 * Cleans directory size cache used by recurse_dirsize(). |
8342 * Cleans directory size cache used by recurse_dirsize(). |
8161 * |
8343 * |
8162 * Removes the current directory and all parent directories from the `dirsize_cache` transient. |
8344 * Removes the current directory and all parent directories from the `dirsize_cache` transient. |
8163 * |
8345 * |
8164 * @since 5.6.0 |
8346 * @since 5.6.0 |
|
8347 * @since 5.9.0 Added input validation with a notice for invalid input. |
8165 * |
8348 * |
8166 * @param string $path Full path of a directory or file. |
8349 * @param string $path Full path of a directory or file. |
8167 */ |
8350 */ |
8168 function clean_dirsize_cache( $path ) { |
8351 function clean_dirsize_cache( $path ) { |
|
8352 if ( ! is_string( $path ) || empty( $path ) ) { |
|
8353 trigger_error( |
|
8354 sprintf( |
|
8355 /* translators: 1: Function name, 2: A variable type, like "boolean" or "integer". */ |
|
8356 __( '%1$s only accepts a non-empty path string, received %2$s.' ), |
|
8357 '<code>clean_dirsize_cache()</code>', |
|
8358 '<code>' . gettype( $path ) . '</code>' |
|
8359 ) |
|
8360 ); |
|
8361 return; |
|
8362 } |
|
8363 |
8169 $directory_cache = get_transient( 'dirsize_cache' ); |
8364 $directory_cache = get_transient( 'dirsize_cache' ); |
8170 |
8365 |
8171 if ( empty( $directory_cache ) ) { |
8366 if ( empty( $directory_cache ) ) { |
8172 return; |
8367 return; |
8173 } |
8368 } |
8174 |
8369 |
8175 $path = untrailingslashit( $path ); |
8370 if ( |
|
8371 strpos( $path, '/' ) === false && |
|
8372 strpos( $path, '\\' ) === false |
|
8373 ) { |
|
8374 unset( $directory_cache[ $path ] ); |
|
8375 set_transient( 'dirsize_cache', $directory_cache ); |
|
8376 return; |
|
8377 } |
|
8378 |
|
8379 $last_path = null; |
|
8380 $path = untrailingslashit( $path ); |
8176 unset( $directory_cache[ $path ] ); |
8381 unset( $directory_cache[ $path ] ); |
8177 |
8382 |
8178 while ( DIRECTORY_SEPARATOR !== $path && '.' !== $path && '..' !== $path ) { |
8383 while ( |
8179 $path = dirname( $path ); |
8384 $last_path !== $path && |
|
8385 DIRECTORY_SEPARATOR !== $path && |
|
8386 '.' !== $path && |
|
8387 '..' !== $path |
|
8388 ) { |
|
8389 $last_path = $path; |
|
8390 $path = dirname( $path ); |
8180 unset( $directory_cache[ $path ] ); |
8391 unset( $directory_cache[ $path ] ); |
8181 } |
8392 } |
8182 |
8393 |
8183 set_transient( 'dirsize_cache', $directory_cache ); |
8394 set_transient( 'dirsize_cache', $directory_cache ); |
8184 } |
8395 } |
8185 |
8396 |
8186 /** |
8397 /** |
8187 * Checks compatibility with the current WordPress version. |
8398 * Checks compatibility with the current WordPress version. |
8188 * |
8399 * |
8189 * @since 5.2.0 |
8400 * @since 5.2.0 |
|
8401 * |
|
8402 * @global string $wp_version The WordPress version string. |
8190 * |
8403 * |
8191 * @param string $required Minimum required WordPress version. |
8404 * @param string $required Minimum required WordPress version. |
8192 * @return bool True if required version is compatible or empty, false if not. |
8405 * @return bool True if required version is compatible or empty, false if not. |
8193 */ |
8406 */ |
8194 function is_wp_version_compatible( $required ) { |
8407 function is_wp_version_compatible( $required ) { |
8195 return empty( $required ) || version_compare( get_bloginfo( 'version' ), $required, '>=' ); |
8408 global $wp_version; |
|
8409 |
|
8410 // Strip off any -alpha, -RC, -beta, -src suffixes. |
|
8411 list( $version ) = explode( '-', $wp_version ); |
|
8412 |
|
8413 return empty( $required ) || version_compare( $version, $required, '>=' ); |
8196 } |
8414 } |
8197 |
8415 |
8198 /** |
8416 /** |
8199 * Checks compatibility with the current PHP version. |
8417 * Checks compatibility with the current PHP version. |
8200 * |
8418 * |
8206 function is_php_version_compatible( $required ) { |
8424 function is_php_version_compatible( $required ) { |
8207 return empty( $required ) || version_compare( phpversion(), $required, '>=' ); |
8425 return empty( $required ) || version_compare( phpversion(), $required, '>=' ); |
8208 } |
8426 } |
8209 |
8427 |
8210 /** |
8428 /** |
8211 * Check if two numbers are nearly the same. |
8429 * Checks if two numbers are nearly the same. |
8212 * |
8430 * |
8213 * This is similar to using `round()` but the precision is more fine-grained. |
8431 * This is similar to using `round()` but the precision is more fine-grained. |
8214 * |
8432 * |
8215 * @since 5.3.0 |
8433 * @since 5.3.0 |
8216 * |
8434 * |
8217 * @param int|float $expected The expected value. |
8435 * @param int|float $expected The expected value. |
8218 * @param int|float $actual The actual number. |
8436 * @param int|float $actual The actual number. |
8219 * @param int|float $precision The allowed variation. |
8437 * @param int|float $precision The allowed variation. |
8220 * @return bool Whether the numbers match whithin the specified precision. |
8438 * @return bool Whether the numbers match within the specified precision. |
8221 */ |
8439 */ |
8222 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { |
8440 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { |
8223 return abs( (float) $expected - (float) $actual ) <= $precision; |
8441 return abs( (float) $expected - (float) $actual ) <= $precision; |
8224 } |
8442 } |
|
8443 |
|
8444 /** |
|
8445 * Sorts the keys of an array alphabetically. |
|
8446 * The array is passed by reference so it doesn't get returned |
|
8447 * which mimics the behaviour of ksort. |
|
8448 * |
|
8449 * @since 6.0.0 |
|
8450 * |
|
8451 * @param array $array The array to sort, passed by reference. |
|
8452 */ |
|
8453 function wp_recursive_ksort( &$array ) { |
|
8454 foreach ( $array as &$value ) { |
|
8455 if ( is_array( $value ) ) { |
|
8456 wp_recursive_ksort( $value ); |
|
8457 } |
|
8458 } |
|
8459 ksort( $array ); |
|
8460 } |