828 * pingbacks and trackbacks. |
828 * pingbacks and trackbacks. |
829 * |
829 * |
830 * @since 1.5.0 |
830 * @since 1.5.0 |
831 * @since 5.3.0 The `$content` parameter was made optional, and the `$post` parameter was |
831 * @since 5.3.0 The `$content` parameter was made optional, and the `$post` parameter was |
832 * updated to accept a post ID or a WP_Post object. |
832 * updated to accept a post ID or a WP_Post object. |
|
833 * @since 5.6.0 The `$content` parameter is no longer optional, but passing `null` to skip it |
|
834 * is still supported. |
833 * |
835 * |
834 * @global wpdb $wpdb WordPress database abstraction object. |
836 * @global wpdb $wpdb WordPress database abstraction object. |
835 * |
837 * |
836 * @param string $content Post content. If `null`, the `post_content` field from `$post` is used. |
838 * @param string|null $content Post content. If `null`, the `post_content` field from `$post` is used. |
837 * @param int|WP_Post $post Post ID or post object. |
839 * @param int|WP_Post $post Post ID or post object. |
838 * @return null|bool Returns false if post is not found. |
840 * @return void|false Void on success, false if the post is not found. |
839 */ |
841 */ |
840 function do_enclose( $content = null, $post ) { |
842 function do_enclose( $content, $post ) { |
841 global $wpdb; |
843 global $wpdb; |
842 |
844 |
843 // @todo Tidy this code and make the debug code optional. |
845 // @todo Tidy this code and make the debug code optional. |
844 include_once ABSPATH . WPINC . '/class-IXR.php'; |
846 include_once ABSPATH . WPINC . '/class-IXR.php'; |
845 |
847 |
1743 * If one or more exist, suggest table repair since we got here because the |
1756 * If one or more exist, suggest table repair since we got here because the |
1744 * options table could not be accessed. |
1757 * options table could not be accessed. |
1745 */ |
1758 */ |
1746 $wp_tables = $wpdb->tables(); |
1759 $wp_tables = $wpdb->tables(); |
1747 foreach ( $wp_tables as $table ) { |
1760 foreach ( $wp_tables as $table ) { |
1748 // The existence of custom user tables shouldn't suggest an insane state or prevent a clean installation. |
1761 // The existence of custom user tables shouldn't suggest an unwise state or prevent a clean installation. |
1749 if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table ) { |
1762 if ( defined( 'CUSTOM_USER_TABLE' ) && CUSTOM_USER_TABLE == $table ) { |
1750 continue; |
1763 continue; |
1751 } |
1764 } |
1752 if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table ) { |
1765 if ( defined( 'CUSTOM_USER_META_TABLE' ) && CUSTOM_USER_META_TABLE == $table ) { |
1753 continue; |
1766 continue; |
1754 } |
1767 } |
1755 |
1768 |
1756 if ( ! $wpdb->get_results( "DESCRIBE $table;" ) ) { |
1769 $described_table = $wpdb->get_results( "DESCRIBE $table;" ); |
|
1770 if ( |
|
1771 ( ! $described_table && empty( $wpdb->last_error ) ) || |
|
1772 ( is_array( $described_table ) && 0 === count( $described_table ) ) |
|
1773 ) { |
1757 continue; |
1774 continue; |
1758 } |
1775 } |
1759 |
1776 |
1760 // One or more tables exist. We are insane. |
1777 // One or more tables exist. This is not good. |
1761 |
1778 |
1762 wp_load_translations_early(); |
1779 wp_load_translations_early(); |
1763 |
1780 |
1764 // Die with a DB error. |
1781 // Die with a DB error. |
1765 $wpdb->error = sprintf( |
1782 $wpdb->error = sprintf( |
2486 * Use callback if supplied. |
2507 * Use callback if supplied. |
2487 */ |
2508 */ |
2488 if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) { |
2509 if ( $unique_filename_callback && is_callable( $unique_filename_callback ) ) { |
2489 $filename = call_user_func( $unique_filename_callback, $dir, $name, $ext ); |
2510 $filename = call_user_func( $unique_filename_callback, $dir, $name, $ext ); |
2490 } else { |
2511 } else { |
2491 $number = ''; |
2512 $fname = pathinfo( $filename, PATHINFO_FILENAME ); |
2492 $fname = pathinfo( $filename, PATHINFO_FILENAME ); |
|
2493 |
2513 |
2494 // Always append a number to file names that can potentially match image sub-size file names. |
2514 // Always append a number to file names that can potentially match image sub-size file names. |
2495 if ( $fname && preg_match( '/-(?:\d+x\d+|scaled|rotated)$/', $fname ) ) { |
2515 if ( $fname && preg_match( '/-(?:\d+x\d+|scaled|rotated)$/', $fname ) ) { |
2496 $number = 1; |
2516 $number = 1; |
2497 |
2517 |
2498 // At this point the file name may not be unique. This is tested below and the $number is incremented. |
2518 // At this point the file name may not be unique. This is tested below and the $number is incremented. |
2499 $filename = str_replace( "{$fname}{$ext}", "{$fname}-{$number}{$ext}", $filename ); |
2519 $filename = str_replace( "{$fname}{$ext}", "{$fname}-{$number}{$ext}", $filename ); |
2500 } |
2520 } |
2501 |
2521 |
2502 // Change '.ext' to lower case. |
2522 // Get the mime type. Uploaded files were already checked with wp_check_filetype_and_ext() |
2503 if ( $ext && strtolower( $ext ) != $ext ) { |
2523 // in _wp_handle_upload(). Using wp_check_filetype() would be sufficient here. |
2504 $ext2 = strtolower( $ext ); |
2524 $file_type = wp_check_filetype( $filename ); |
2505 $filename2 = preg_replace( '|' . preg_quote( $ext ) . '$|', $ext2, $filename ); |
2525 $mime_type = $file_type['type']; |
2506 |
2526 |
2507 // Check for both lower and upper case extension or image sub-sizes may be overwritten. |
2527 $is_image = ( ! empty( $mime_type ) && 0 === strpos( $mime_type, 'image/' ) ); |
2508 while ( file_exists( $dir . "/{$filename}" ) || file_exists( $dir . "/{$filename2}" ) ) { |
2528 $upload_dir = wp_get_upload_dir(); |
2509 $new_number = (int) $number + 1; |
2529 $lc_filename = null; |
2510 $filename = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename ); |
2530 |
2511 $filename2 = str_replace( array( "-{$number}{$ext2}", "{$number}{$ext2}" ), "-{$new_number}{$ext2}", $filename2 ); |
2531 $lc_ext = strtolower( $ext ); |
2512 $number = $new_number; |
2532 $_dir = trailingslashit( $dir ); |
|
2533 |
|
2534 // If the extension is uppercase add an alternate file name with lowercase extension. Both need to be tested |
|
2535 // for uniqueness as the extension will be changed to lowercase for better compatibility with different filesystems. |
|
2536 // Fixes an inconsistency in WP < 2.9 where uppercase extensions were allowed but image sub-sizes were created with |
|
2537 // lowercase extensions. |
|
2538 if ( $ext && $lc_ext !== $ext ) { |
|
2539 $lc_filename = preg_replace( '|' . preg_quote( $ext ) . '$|', $lc_ext, $filename ); |
|
2540 } |
|
2541 |
|
2542 // Increment the number added to the file name if there are any files in $dir whose names match one of the |
|
2543 // possible name variations. |
|
2544 while ( file_exists( $_dir . $filename ) || ( $lc_filename && file_exists( $_dir . $lc_filename ) ) ) { |
|
2545 $new_number = (int) $number + 1; |
|
2546 |
|
2547 if ( $lc_filename ) { |
|
2548 $lc_filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $lc_filename ); |
2513 } |
2549 } |
2514 |
2550 |
2515 $filename = $filename2; |
2551 if ( '' === "{$number}{$ext}" ) { |
2516 } else { |
2552 $filename = "{$filename}-{$new_number}"; |
2517 while ( file_exists( $dir . "/{$filename}" ) ) { |
2553 } else { |
2518 $new_number = (int) $number + 1; |
2554 $filename = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename ); |
2519 |
|
2520 if ( '' === "{$number}{$ext}" ) { |
|
2521 $filename = "{$filename}-{$new_number}"; |
|
2522 } else { |
|
2523 $filename = str_replace( array( "-{$number}{$ext}", "{$number}{$ext}" ), "-{$new_number}{$ext}", $filename ); |
|
2524 } |
|
2525 |
|
2526 $number = $new_number; |
|
2527 } |
2555 } |
|
2556 |
|
2557 $number = $new_number; |
|
2558 } |
|
2559 |
|
2560 // Change the extension to lowercase if needed. |
|
2561 if ( $lc_filename ) { |
|
2562 $filename = $lc_filename; |
2528 } |
2563 } |
2529 |
2564 |
2530 // Prevent collisions with existing file names that contain dimension-like strings |
2565 // Prevent collisions with existing file names that contain dimension-like strings |
2531 // (whether they are subsizes or originals uploaded prior to #42437). |
2566 // (whether they are subsizes or originals uploaded prior to #42437). |
2532 $upload_dir = wp_get_upload_dir(); |
2567 |
|
2568 $files = array(); |
|
2569 $count = 10000; |
2533 |
2570 |
2534 // The (resized) image files would have name and extension, and will be in the uploads dir. |
2571 // The (resized) image files would have name and extension, and will be in the uploads dir. |
2535 if ( $name && $ext && @is_dir( $dir ) && false !== strpos( $dir, $upload_dir['basedir'] ) ) { |
2572 if ( $name && $ext && @is_dir( $dir ) && false !== strpos( $dir, $upload_dir['basedir'] ) ) { |
2536 /** |
2573 /** |
2537 * Filters the file list used for calculating a unique filename for a newly added file. |
2574 * Filters the file list used for calculating a unique filename for a newly added file. |
2557 // Remove "dot" dirs. |
2594 // Remove "dot" dirs. |
2558 $files = array_diff( $files, array( '.', '..' ) ); |
2595 $files = array_diff( $files, array( '.', '..' ) ); |
2559 } |
2596 } |
2560 |
2597 |
2561 if ( ! empty( $files ) ) { |
2598 if ( ! empty( $files ) ) { |
2562 // The extension case may have changed above. |
2599 $count = count( $files ); |
2563 $new_ext = ! empty( $ext2 ) ? $ext2 : $ext; |
|
2564 |
2600 |
2565 // Ensure this never goes into infinite loop |
2601 // Ensure this never goes into infinite loop |
2566 // as it uses pathinfo() and regex in the check, but string replacement for the changes. |
2602 // as it uses pathinfo() and regex in the check, but string replacement for the changes. |
2567 $count = count( $files ); |
2603 $i = 0; |
2568 $i = 0; |
|
2569 |
2604 |
2570 while ( $i <= $count && _wp_check_existing_file_names( $filename, $files ) ) { |
2605 while ( $i <= $count && _wp_check_existing_file_names( $filename, $files ) ) { |
2571 $new_number = (int) $number + 1; |
2606 $new_number = (int) $number + 1; |
2572 $filename = str_replace( array( "-{$number}{$new_ext}", "{$number}{$new_ext}" ), "-{$new_number}{$new_ext}", $filename ); |
2607 |
2573 $number = $new_number; |
2608 // 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 ); |
|
2610 |
|
2611 $number = $new_number; |
2574 $i++; |
2612 $i++; |
2575 } |
2613 } |
2576 } |
2614 } |
2577 } |
2615 } |
|
2616 |
|
2617 // Check if an image will be converted after uploading or some existing images sub-sizes file names may conflict |
|
2618 // when regenerated. If yes, ensure the new file name will be unique and will produce unique sub-sizes. |
|
2619 if ( $is_image ) { |
|
2620 $output_formats = apply_filters( 'image_editor_output_format', array(), $_dir . $filename, $mime_type ); |
|
2621 $alt_types = array(); |
|
2622 |
|
2623 if ( ! empty( $output_formats[ $mime_type ] ) ) { |
|
2624 // The image will be converted to this format/mime type. |
|
2625 $alt_mime_type = $output_formats[ $mime_type ]; |
|
2626 |
|
2627 // Other types of images whose names may conflict if their sub-sizes are regenerated. |
|
2628 $alt_types = array_keys( array_intersect( $output_formats, array( $mime_type, $alt_mime_type ) ) ); |
|
2629 $alt_types[] = $alt_mime_type; |
|
2630 } elseif ( ! empty( $output_formats ) ) { |
|
2631 $alt_types = array_keys( array_intersect( $output_formats, array( $mime_type ) ) ); |
|
2632 } |
|
2633 |
|
2634 // Remove duplicates and the original mime type. It will be added later if needed. |
|
2635 $alt_types = array_unique( array_diff( $alt_types, array( $mime_type ) ) ); |
|
2636 |
|
2637 foreach ( $alt_types as $alt_type ) { |
|
2638 $alt_ext = wp_get_default_extension_for_mime_type( $alt_type ); |
|
2639 |
|
2640 if ( ! $alt_ext ) { |
|
2641 continue; |
|
2642 } |
|
2643 |
|
2644 $alt_ext = ".{$alt_ext}"; |
|
2645 $alt_filename = preg_replace( '|' . preg_quote( $lc_ext ) . '$|', $alt_ext, $filename ); |
|
2646 |
|
2647 $alt_filenames[ $alt_ext ] = $alt_filename; |
|
2648 } |
|
2649 |
|
2650 if ( ! empty( $alt_filenames ) ) { |
|
2651 // Add the original filename. It needs to be checked again together with the alternate filenames |
|
2652 // when $number is incremented. |
|
2653 $alt_filenames[ $lc_ext ] = $filename; |
|
2654 |
|
2655 // Ensure no infinite loop. |
|
2656 $i = 0; |
|
2657 |
|
2658 while ( $i <= $count && _wp_check_alternate_file_names( $alt_filenames, $_dir, $files ) ) { |
|
2659 $new_number = (int) $number + 1; |
|
2660 |
|
2661 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 ); |
|
2663 } |
|
2664 |
|
2665 // Also update the $number in (the output) $filename. |
|
2666 // If the extension was uppercase it was already replaced with the lowercase version. |
|
2667 $filename = str_replace( array( "-{$number}{$lc_ext}", "{$number}{$lc_ext}" ), "-{$new_number}{$lc_ext}", $filename ); |
|
2668 |
|
2669 $number = $new_number; |
|
2670 $i++; |
|
2671 } |
|
2672 } |
|
2673 } |
2578 } |
2674 } |
2579 |
2675 |
2580 /** |
2676 /** |
2581 * Filters the result when generating a unique file name. |
2677 * Filters the result when generating a unique file name. |
2582 * |
2678 * |
2583 * @since 4.5.0 |
2679 * @since 4.5.0 |
|
2680 * @since 5.8.1 The `$alt_filenames` and `$number` parameters were added. |
2584 * |
2681 * |
2585 * @param string $filename Unique file name. |
2682 * @param string $filename Unique file name. |
2586 * @param string $ext File extension, eg. ".png". |
2683 * @param string $ext File extension, eg. ".png". |
2587 * @param string $dir Directory path. |
2684 * @param string $dir Directory path. |
2588 * @param callable|null $unique_filename_callback Callback function that generates the unique file name. |
2685 * @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. |
|
2687 * @param int|string $number The highest number that was used to make the file name unique |
|
2688 * or an empty string if unused. |
2589 */ |
2689 */ |
2590 return apply_filters( 'wp_unique_filename', $filename, $ext, $dir, $unique_filename_callback ); |
2690 return apply_filters( 'wp_unique_filename', $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number ); |
|
2691 } |
|
2692 |
|
2693 /** |
|
2694 * Helper function to test if each of an array of file names could conflict with existing files. |
|
2695 * |
|
2696 * @since 5.8.1 |
|
2697 * @access private |
|
2698 * |
|
2699 * @param string[] $filenames Array of file names to check. |
|
2700 * @param string $dir The directory containing the files. |
|
2701 * @param array $files An array of existing files in the directory. May be empty. |
|
2702 * @return bool True if the tested file name could match an existing file, false otherwise. |
|
2703 */ |
|
2704 function _wp_check_alternate_file_names( $filenames, $dir, $files ) { |
|
2705 foreach ( $filenames as $filename ) { |
|
2706 if ( file_exists( $dir . $filename ) ) { |
|
2707 return true; |
|
2708 } |
|
2709 |
|
2710 if ( ! empty( $files ) && _wp_check_existing_file_names( $filename, $files ) ) { |
|
2711 return true; |
|
2712 } |
|
2713 } |
|
2714 |
|
2715 return false; |
2591 } |
2716 } |
2592 |
2717 |
2593 /** |
2718 /** |
2594 * Helper function to check if a file name could match an existing image sub-size file name. |
2719 * Helper function to check if a file name could match an existing image sub-size file name. |
2595 * |
2720 * |
2768 } |
2897 } |
2769 } |
2898 } |
2770 } |
2899 } |
2771 |
2900 |
2772 /** |
2901 /** |
|
2902 * Returns first matched extension for the mime-type, |
|
2903 * as mapped from wp_get_mime_types(). |
|
2904 * |
|
2905 * @since 5.8.1 |
|
2906 * |
|
2907 * @param string $mime_type |
|
2908 * |
|
2909 * @return string|false |
|
2910 */ |
|
2911 function wp_get_default_extension_for_mime_type( $mime_type ) { |
|
2912 $extensions = explode( '|', array_search( $mime_type, wp_get_mime_types(), true ) ); |
|
2913 |
|
2914 if ( empty( $extensions[0] ) ) { |
|
2915 return false; |
|
2916 } |
|
2917 |
|
2918 return $extensions[0]; |
|
2919 } |
|
2920 |
|
2921 /** |
2773 * Retrieve the file type from the file name. |
2922 * Retrieve the file type from the file name. |
2774 * |
2923 * |
2775 * You can optionally define the mime array, if needed. |
2924 * You can optionally define the mime array, if needed. |
2776 * |
2925 * |
2777 * @since 2.0.4 |
2926 * @since 2.0.4 |
2778 * |
2927 * |
2779 * @param string $filename File name or path. |
2928 * @param string $filename File name or path. |
2780 * @param string[] $mimes Optional. Array of mime types keyed by their file extension regex. |
2929 * @param string[] $mimes Optional. Array of allowed mime types keyed by their file extension regex. |
2781 * @return array { |
2930 * @return array { |
2782 * Values for the extension and mime type. |
2931 * Values for the extension and mime type. |
2783 * |
2932 * |
2784 * @type string|false $ext File extension, or false if the file doesn't match a mime type. |
2933 * @type string|false $ext File extension, or false if the file doesn't match a mime type. |
2785 * @type string|false $type File mime type, or false if the file doesn't match a mime type. |
2934 * @type string|false $type File mime type, or false if the file doesn't match a mime type. |
2982 * Filters the "real" file type of the given file. |
3148 * Filters the "real" file type of the given file. |
2983 * |
3149 * |
2984 * @since 3.0.0 |
3150 * @since 3.0.0 |
2985 * @since 5.1.0 The $real_mime parameter was added. |
3151 * @since 5.1.0 The $real_mime parameter was added. |
2986 * |
3152 * |
2987 * @param array $wp_check_filetype_and_ext { |
3153 * @param array $wp_check_filetype_and_ext { |
2988 * Values for the extension, mime type, and corrected filename. |
3154 * Values for the extension, mime type, and corrected filename. |
2989 * |
3155 * |
2990 * @type string|false $ext File extension, or false if the file doesn't match a mime type. |
3156 * @type string|false $ext File extension, or false if the file doesn't match a mime type. |
2991 * @type string|false $type File mime type, or false if the file doesn't match a mime type. |
3157 * @type string|false $type File mime type, or false if the file doesn't match a mime type. |
2992 * @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined. |
3158 * @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined. |
2993 * } |
3159 * } |
2994 * @param string $file Full path to the file. |
3160 * @param string $file Full path to the file. |
2995 * @param string $filename The name of the file (may differ from $file due to |
3161 * @param string $filename The name of the file (may differ from $file due to |
2996 * $file being in a tmp directory). |
3162 * $file being in a tmp directory). |
2997 * @param string[] $mimes Array of mime types keyed by their file extension regex. |
3163 * @param string[] $mimes Array of mime types keyed by their file extension regex. |
2998 * @param string|bool $real_mime The actual mime type or false if the type cannot be determined. |
3164 * @param string|false $real_mime The actual mime type or false if the type cannot be determined. |
2999 */ |
3165 */ |
3000 return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime ); |
3166 return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime ); |
3001 } |
3167 } |
3002 |
3168 |
3003 /** |
3169 /** |
3004 * Returns the real mime type of an image file. |
3170 * Returns the real mime type of an image file. |
3005 * |
3171 * |
3006 * This depends on exif_imagetype() or getimagesize() to determine real mime types. |
3172 * This depends on exif_imagetype() or getimagesize() to determine real mime types. |
3007 * |
3173 * |
3008 * @since 4.7.1 |
3174 * @since 4.7.1 |
|
3175 * @since 5.8.0 Added support for WebP images. |
3009 * |
3176 * |
3010 * @param string $file Full path to the file. |
3177 * @param string $file Full path to the file. |
3011 * @return string|false The actual mime type or false if the type cannot be determined. |
3178 * @return string|false The actual mime type or false if the type cannot be determined. |
3012 */ |
3179 */ |
3013 function wp_get_image_mime( $file ) { |
3180 function wp_get_image_mime( $file ) { |
3019 try { |
3186 try { |
3020 if ( is_callable( 'exif_imagetype' ) ) { |
3187 if ( is_callable( 'exif_imagetype' ) ) { |
3021 $imagetype = exif_imagetype( $file ); |
3188 $imagetype = exif_imagetype( $file ); |
3022 $mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false; |
3189 $mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false; |
3023 } elseif ( function_exists( 'getimagesize' ) ) { |
3190 } elseif ( function_exists( 'getimagesize' ) ) { |
3024 $imagesize = @getimagesize( $file ); |
3191 // Don't silence errors when in debug mode, unless running unit tests. |
3025 $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false; |
3192 if ( defined( 'WP_DEBUG' ) && WP_DEBUG |
|
3193 && ! defined( 'WP_RUN_CORE_TESTS' ) |
|
3194 ) { |
|
3195 // Not using wp_getimagesize() here to avoid an infinite loop. |
|
3196 $imagesize = getimagesize( $file ); |
|
3197 } else { |
|
3198 // phpcs:ignore WordPress.PHP.NoSilencedErrors |
|
3199 $imagesize = @getimagesize( $file ); |
|
3200 } |
|
3201 |
|
3202 $mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false; |
3026 } else { |
3203 } else { |
3027 $mime = false; |
3204 $mime = false; |
3028 } |
3205 } |
|
3206 |
|
3207 if ( false !== $mime ) { |
|
3208 return $mime; |
|
3209 } |
|
3210 |
|
3211 $handle = fopen( $file, 'rb' ); |
|
3212 if ( false === $handle ) { |
|
3213 return false; |
|
3214 } |
|
3215 |
|
3216 $magic = fread( $handle, 12 ); |
|
3217 if ( false === $magic ) { |
|
3218 return false; |
|
3219 } |
|
3220 |
|
3221 /* |
|
3222 * Add WebP fallback detection when image library doesn't support WebP. |
|
3223 * Note: detection values come from LibWebP, see |
|
3224 * https://github.com/webmproject/libwebp/blob/master/imageio/image_dec.c#L30 |
|
3225 */ |
|
3226 $magic = bin2hex( $magic ); |
|
3227 if ( |
|
3228 // RIFF. |
|
3229 ( 0 === strpos( $magic, '52494646' ) ) && |
|
3230 // WEBP. |
|
3231 ( 16 === strpos( $magic, '57454250' ) ) |
|
3232 ) { |
|
3233 $mime = 'image/webp'; |
|
3234 } |
|
3235 |
|
3236 fclose( $handle ); |
3029 } catch ( Exception $e ) { |
3237 } catch ( Exception $e ) { |
3030 $mime = false; |
3238 $mime = false; |
3031 } |
3239 } |
3032 |
3240 |
3033 return $mime; |
3241 return $mime; |
3183 * @param array[] $ext2type Multi-dimensional array of file extensions types keyed by the type of file. |
3392 * @param array[] $ext2type Multi-dimensional array of file extensions types keyed by the type of file. |
3184 */ |
3393 */ |
3185 return apply_filters( |
3394 return apply_filters( |
3186 'ext2type', |
3395 'ext2type', |
3187 array( |
3396 array( |
3188 'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic' ), |
3397 'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp' ), |
3189 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ), |
3398 'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ), |
3190 'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ), |
3399 'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ), |
3191 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ), |
3400 'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ), |
3192 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ), |
3401 'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ), |
3193 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ), |
3402 'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ), |
3459 <html <?php echo $dir_attr; ?>> |
3668 <html <?php echo $dir_attr; ?>> |
3460 <head> |
3669 <head> |
3461 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" /> |
3670 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" /> |
3462 <meta name="viewport" content="width=device-width"> |
3671 <meta name="viewport" content="width=device-width"> |
3463 <?php |
3672 <?php |
3464 if ( function_exists( 'wp_no_robots' ) ) { |
3673 if ( function_exists( 'wp_robots' ) && function_exists( 'wp_robots_no_robots' ) && function_exists( 'add_filter' ) ) { |
3465 wp_no_robots(); |
3674 add_filter( 'wp_robots', 'wp_robots_no_robots' ); |
|
3675 wp_robots(); |
3466 } |
3676 } |
3467 ?> |
3677 ?> |
3468 <title><?php echo $title; ?></title> |
3678 <title><?php echo $title; ?></title> |
3469 <style type="text/css"> |
3679 <style type="text/css"> |
3470 html { |
3680 html { |
3471 background: #f1f1f1; |
3681 background: #f1f1f1; |
3472 } |
3682 } |
3473 body { |
3683 body { |
3474 background: #fff; |
3684 background: #fff; |
|
3685 border: 1px solid #ccd0d4; |
3475 color: #444; |
3686 color: #444; |
3476 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; |
3687 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; |
3477 margin: 2em auto; |
3688 margin: 2em auto; |
3478 padding: 1em 2em; |
3689 padding: 1em 2em; |
3479 max-width: 700px; |
3690 max-width: 700px; |
3480 -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13); |
3691 -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .04); |
3481 box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13); |
3692 box-shadow: 0 1px 1px rgba(0, 0, 0, .04); |
3482 } |
3693 } |
3483 h1 { |
3694 h1 { |
3484 border-bottom: 1px solid #dadada; |
3695 border-bottom: 1px solid #dadada; |
3485 clear: both; |
3696 clear: both; |
3486 color: #666; |
3697 color: #666; |
3540 white-space: nowrap; |
3751 white-space: nowrap; |
3541 -webkit-box-sizing: border-box; |
3752 -webkit-box-sizing: border-box; |
3542 -moz-box-sizing: border-box; |
3753 -moz-box-sizing: border-box; |
3543 box-sizing: border-box; |
3754 box-sizing: border-box; |
3544 |
3755 |
3545 -webkit-box-shadow: 0 1px 0 #ccc; |
|
3546 box-shadow: 0 1px 0 #ccc; |
|
3547 vertical-align: top; |
3756 vertical-align: top; |
3548 } |
3757 } |
3549 |
3758 |
3550 .button.button-large { |
3759 .button.button-large { |
3551 height: 30px; |
3760 line-height: 2.30769231; |
3552 line-height: 2.15384615; |
3761 min-height: 32px; |
3553 padding: 0 12px 2px; |
3762 padding: 0 12px; |
3554 } |
3763 } |
3555 |
3764 |
3556 .button:hover, |
3765 .button:hover, |
3557 .button:focus { |
3766 .button:focus { |
3558 background: #fafafa; |
3767 background: #f1f1f1; |
3559 border-color: #999; |
|
3560 color: #23282d; |
|
3561 } |
3768 } |
3562 |
3769 |
3563 .button:focus { |
3770 .button:focus { |
3564 border-color: #5b9dd9; |
3771 background: #f3f5f6; |
3565 -webkit-box-shadow: 0 0 3px rgba(0, 115, 170, 0.8); |
3772 border-color: #007cba; |
3566 box-shadow: 0 0 3px rgba(0, 115, 170, 0.8); |
3773 -webkit-box-shadow: 0 0 0 1px #007cba; |
3567 outline: none; |
3774 box-shadow: 0 0 0 1px #007cba; |
|
3775 color: #016087; |
|
3776 outline: 2px solid transparent; |
|
3777 outline-offset: 0; |
3568 } |
3778 } |
3569 |
3779 |
3570 .button:active { |
3780 .button:active { |
3571 background: #eee; |
3781 background: #f3f5f6; |
3572 border-color: #999; |
3782 border-color: #7e8993; |
3573 -webkit-box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5); |
3783 -webkit-box-shadow: none; |
3574 box-shadow: inset 0 2px 5px -3px rgba(0, 0, 0, 0.5); |
3784 box-shadow: none; |
3575 } |
3785 } |
3576 |
3786 |
3577 <?php |
3787 <?php |
3578 if ( 'rtl' === $text_direction ) { |
3788 if ( 'rtl' === $text_direction ) { |
3579 echo 'body { font-family: Tahoma, Arial; }'; |
3789 echo 'body { font-family: Tahoma, Arial; }'; |
4099 /** |
4311 /** |
4100 * Send a JSON response back to an Ajax request, indicating success. |
4312 * Send a JSON response back to an Ajax request, indicating success. |
4101 * |
4313 * |
4102 * @since 3.5.0 |
4314 * @since 3.5.0 |
4103 * @since 4.7.0 The `$status_code` parameter was added. |
4315 * @since 4.7.0 The `$status_code` parameter was added. |
4104 * |
4316 * @since 5.6.0 The `$options` parameter was added. |
4105 * @param mixed $data Data to encode as JSON, then print and die. |
4317 * |
4106 * @param int $status_code The HTTP status code to output. |
4318 * @param mixed $data Optional. Data to encode as JSON, then print and die. Default null. |
4107 */ |
4319 * @param int $status_code Optional. The HTTP status code to output. Default null. |
4108 function wp_send_json_success( $data = null, $status_code = null ) { |
4320 * @param int $options Optional. Options to be passed to json_encode(). Default 0. |
|
4321 */ |
|
4322 function wp_send_json_success( $data = null, $status_code = null, $options = 0 ) { |
4109 $response = array( 'success' => true ); |
4323 $response = array( 'success' => true ); |
4110 |
4324 |
4111 if ( isset( $data ) ) { |
4325 if ( isset( $data ) ) { |
4112 $response['data'] = $data; |
4326 $response['data'] = $data; |
4113 } |
4327 } |
4114 |
4328 |
4115 wp_send_json( $response, $status_code ); |
4329 wp_send_json( $response, $status_code, $options ); |
4116 } |
4330 } |
4117 |
4331 |
4118 /** |
4332 /** |
4119 * Send a JSON response back to an Ajax request, indicating failure. |
4333 * Send a JSON response back to an Ajax request, indicating failure. |
4120 * |
4334 * |
4424 } |
4640 } |
4425 return $parsed_args; |
4641 return $parsed_args; |
4426 } |
4642 } |
4427 |
4643 |
4428 /** |
4644 /** |
4429 * Cleans up an array, comma- or space-separated list of scalar values. |
4645 * Converts a comma- or space-separated list of scalar values to an array. |
4430 * |
4646 * |
4431 * @since 5.1.0 |
4647 * @since 5.1.0 |
4432 * |
4648 * |
4433 * @param array|string $list List of values. |
4649 * @param array|string $list List of values. |
4434 * @return array Sanitized array of values. |
4650 * @return array Array of values. |
4435 */ |
4651 */ |
4436 function wp_parse_list( $list ) { |
4652 function wp_parse_list( $list ) { |
4437 if ( ! is_array( $list ) ) { |
4653 if ( ! is_array( $list ) ) { |
4438 return preg_split( '/[\s,]+/', $list, -1, PREG_SPLIT_NO_EMPTY ); |
4654 return preg_split( '/[\s,]+/', $list, -1, PREG_SPLIT_NO_EMPTY ); |
4439 } |
4655 } |
4440 |
4656 |
4441 return $list; |
4657 return $list; |
4442 } |
4658 } |
4443 |
4659 |
4444 /** |
4660 /** |
4445 * Clean up an array, comma- or space-separated list of IDs. |
4661 * Cleans up an array, comma- or space-separated list of IDs. |
4446 * |
4662 * |
4447 * @since 3.0.0 |
4663 * @since 3.0.0 |
|
4664 * @since 5.1.0 Refactored to use wp_parse_list(). |
4448 * |
4665 * |
4449 * @param array|string $list List of IDs. |
4666 * @param array|string $list List of IDs. |
4450 * @return int[] Sanitized array of IDs. |
4667 * @return int[] Sanitized array of IDs. |
4451 */ |
4668 */ |
4452 function wp_parse_id_list( $list ) { |
4669 function wp_parse_id_list( $list ) { |
4478 * @param array $keys The list of keys. |
4696 * @param array $keys The list of keys. |
4479 * @return array The array slice. |
4697 * @return array The array slice. |
4480 */ |
4698 */ |
4481 function wp_array_slice_assoc( $array, $keys ) { |
4699 function wp_array_slice_assoc( $array, $keys ) { |
4482 $slice = array(); |
4700 $slice = array(); |
|
4701 |
4483 foreach ( $keys as $key ) { |
4702 foreach ( $keys as $key ) { |
4484 if ( isset( $array[ $key ] ) ) { |
4703 if ( isset( $array[ $key ] ) ) { |
4485 $slice[ $key ] = $array[ $key ]; |
4704 $slice[ $key ] = $array[ $key ]; |
4486 } |
4705 } |
4487 } |
4706 } |
4488 |
4707 |
4489 return $slice; |
4708 return $slice; |
4490 } |
4709 } |
4491 |
4710 |
4492 /** |
4711 /** |
|
4712 * Accesses an array in depth based on a path of keys. |
|
4713 * |
|
4714 * It is the PHP equivalent of JavaScript's `lodash.get()` and mirroring it may help other components |
|
4715 * retain some symmetry between client and server implementations. |
|
4716 * |
|
4717 * Example usage: |
|
4718 * |
|
4719 * $array = array( |
|
4720 * 'a' => array( |
|
4721 * 'b' => array( |
|
4722 * 'c' => 1, |
|
4723 * ), |
|
4724 * ), |
|
4725 * ); |
|
4726 * _wp_array_get( $array, array( 'a', 'b', 'c' ) ); |
|
4727 * |
|
4728 * @internal |
|
4729 * |
|
4730 * @since 5.6.0 |
|
4731 * @access private |
|
4732 * |
|
4733 * @param array $array An array from which we want to retrieve some information. |
|
4734 * @param array $path An array of keys describing the path with which to retrieve information. |
|
4735 * @param mixed $default The return value if the path does not exist within the array, |
|
4736 * or if `$array` or `$path` are not arrays. |
|
4737 * @return mixed The value from the path specified. |
|
4738 */ |
|
4739 function _wp_array_get( $array, $path, $default = null ) { |
|
4740 // Confirm $path is valid. |
|
4741 if ( ! is_array( $path ) || 0 === count( $path ) ) { |
|
4742 return $default; |
|
4743 } |
|
4744 |
|
4745 foreach ( $path as $path_element ) { |
|
4746 if ( |
|
4747 ! is_array( $array ) || |
|
4748 ( ! is_string( $path_element ) && ! is_integer( $path_element ) && ! is_null( $path_element ) ) || |
|
4749 ! array_key_exists( $path_element, $array ) |
|
4750 ) { |
|
4751 return $default; |
|
4752 } |
|
4753 $array = $array[ $path_element ]; |
|
4754 } |
|
4755 |
|
4756 return $array; |
|
4757 } |
|
4758 |
|
4759 /** |
|
4760 * Sets an array in depth based on a path of keys. |
|
4761 * |
|
4762 * It is the PHP equivalent of JavaScript's `lodash.set()` and mirroring it may help other components |
|
4763 * retain some symmetry between client and server implementations. |
|
4764 * |
|
4765 * Example usage: |
|
4766 * |
|
4767 * $array = array(); |
|
4768 * _wp_array_set( $array, array( 'a', 'b', 'c', 1 ) ); |
|
4769 * |
|
4770 * $array becomes: |
|
4771 * array( |
|
4772 * 'a' => array( |
|
4773 * 'b' => array( |
|
4774 * 'c' => 1, |
|
4775 * ), |
|
4776 * ), |
|
4777 * ); |
|
4778 * |
|
4779 * @internal |
|
4780 * |
|
4781 * @since 5.8.0 |
|
4782 * @access private |
|
4783 * |
|
4784 * @param array $array An array that we want to mutate to include a specific value in a path. |
|
4785 * @param array $path An array of keys describing the path that we want to mutate. |
|
4786 * @param mixed $value The value that will be set. |
|
4787 */ |
|
4788 function _wp_array_set( &$array, $path, $value = null ) { |
|
4789 // Confirm $array is valid. |
|
4790 if ( ! is_array( $array ) ) { |
|
4791 return; |
|
4792 } |
|
4793 |
|
4794 // Confirm $path is valid. |
|
4795 if ( ! is_array( $path ) ) { |
|
4796 return; |
|
4797 } |
|
4798 |
|
4799 $path_length = count( $path ); |
|
4800 |
|
4801 if ( 0 === $path_length ) { |
|
4802 return; |
|
4803 } |
|
4804 |
|
4805 foreach ( $path as $path_element ) { |
|
4806 if ( |
|
4807 ! is_string( $path_element ) && ! is_integer( $path_element ) && |
|
4808 ! is_null( $path_element ) |
|
4809 ) { |
|
4810 return; |
|
4811 } |
|
4812 } |
|
4813 |
|
4814 for ( $i = 0; $i < $path_length - 1; ++$i ) { |
|
4815 $path_element = $path[ $i ]; |
|
4816 if ( |
|
4817 ! array_key_exists( $path_element, $array ) || |
|
4818 ! is_array( $array[ $path_element ] ) |
|
4819 ) { |
|
4820 $array[ $path_element ] = array(); |
|
4821 } |
|
4822 $array = &$array[ $path_element ]; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.VariableRedeclaration |
|
4823 } |
|
4824 |
|
4825 $array[ $path[ $i ] ] = $value; |
|
4826 } |
|
4827 |
|
4828 /** |
|
4829 * This function is trying to replicate what |
|
4830 * lodash's kebabCase (JS library) does in the client. |
|
4831 * |
|
4832 * The reason we need this function is that we do some processing |
|
4833 * in both the client and the server (e.g.: we generate |
|
4834 * preset classes from preset slugs) that needs to |
|
4835 * create the same output. |
|
4836 * |
|
4837 * We can't remove or update the client's library due to backward compatibility |
|
4838 * (some of the output of lodash's kebabCase is saved in the post content). |
|
4839 * We have to make the server behave like the client. |
|
4840 * |
|
4841 * Changes to this function should follow updates in the client |
|
4842 * with the same logic. |
|
4843 * |
|
4844 * @link https://github.com/lodash/lodash/blob/4.17/dist/lodash.js#L14369 |
|
4845 * @link https://github.com/lodash/lodash/blob/4.17/dist/lodash.js#L278 |
|
4846 * @link https://github.com/lodash-php/lodash-php/blob/master/src/String/kebabCase.php |
|
4847 * @link https://github.com/lodash-php/lodash-php/blob/master/src/internal/unicodeWords.php |
|
4848 * |
|
4849 * @param string $string The string to kebab-case. |
|
4850 * |
|
4851 * @return string kebab-cased-string. |
|
4852 */ |
|
4853 function _wp_to_kebab_case( $string ) { |
|
4854 //phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
|
4855 // ignore the camelCase names for variables so the names are the same as lodash |
|
4856 // so comparing and porting new changes is easier. |
|
4857 |
|
4858 /* |
|
4859 * Some notable things we've removed compared to the lodash version are: |
|
4860 * |
|
4861 * - non-alphanumeric characters: rsAstralRange, rsEmoji, etc |
|
4862 * - the groups that processed the apostrophe, as it's removed before passing the string to preg_match: rsApos, rsOptContrLower, and rsOptContrUpper |
|
4863 * |
|
4864 */ |
|
4865 |
|
4866 /** Used to compose unicode character classes. */ |
|
4867 $rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff'; |
|
4868 $rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf'; |
|
4869 $rsPunctuationRange = '\\x{2000}-\\x{206f}'; |
|
4870 $rsSpaceRange = ' \\t\\x0b\\f\\xa0\\x{feff}\\n\\r\\x{2028}\\x{2029}\\x{1680}\\x{180e}\\x{2000}\\x{2001}\\x{2002}\\x{2003}\\x{2004}\\x{2005}\\x{2006}\\x{2007}\\x{2008}\\x{2009}\\x{200a}\\x{202f}\\x{205f}\\x{3000}'; |
|
4871 $rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde'; |
|
4872 $rsBreakRange = $rsNonCharRange . $rsPunctuationRange . $rsSpaceRange; |
|
4873 |
|
4874 /** Used to compose unicode capture groups. */ |
|
4875 $rsBreak = '[' . $rsBreakRange . ']'; |
|
4876 $rsDigits = '\\d+'; // The last lodash version in GitHub uses a single digit here and expands it when in use. |
|
4877 $rsLower = '[' . $rsLowerRange . ']'; |
|
4878 $rsMisc = '[^' . $rsBreakRange . $rsDigits . $rsLowerRange . $rsUpperRange . ']'; |
|
4879 $rsUpper = '[' . $rsUpperRange . ']'; |
|
4880 |
|
4881 /** Used to compose unicode regexes. */ |
|
4882 $rsMiscLower = '(?:' . $rsLower . '|' . $rsMisc . ')'; |
|
4883 $rsMiscUpper = '(?:' . $rsUpper . '|' . $rsMisc . ')'; |
|
4884 $rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])'; |
|
4885 $rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])'; |
|
4886 |
|
4887 $regexp = '/' . implode( |
|
4888 '|', |
|
4889 array( |
|
4890 $rsUpper . '?' . $rsLower . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper, '$' ) ) . ')', |
|
4891 $rsMiscUpper . '+' . '(?=' . implode( '|', array( $rsBreak, $rsUpper . $rsMiscLower, '$' ) ) . ')', |
|
4892 $rsUpper . '?' . $rsMiscLower . '+', |
|
4893 $rsUpper . '+', |
|
4894 $rsOrdUpper, |
|
4895 $rsOrdLower, |
|
4896 $rsDigits, |
|
4897 ) |
|
4898 ) . '/u'; |
|
4899 |
|
4900 preg_match_all( $regexp, str_replace( "'", '', $string ), $matches ); |
|
4901 return strtolower( implode( '-', $matches[0] ) ); |
|
4902 //phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase |
|
4903 } |
|
4904 |
|
4905 /** |
4493 * Determines if the variable is a numeric-indexed array. |
4906 * Determines if the variable is a numeric-indexed array. |
4494 * |
4907 * |
4495 * @since 4.4.0 |
4908 * @since 4.4.0 |
4496 * |
4909 * |
4497 * @param mixed $data Variable to check. |
4910 * @param mixed $data Variable to check. |
4502 return false; |
4915 return false; |
4503 } |
4916 } |
4504 |
4917 |
4505 $keys = array_keys( $data ); |
4918 $keys = array_keys( $data ); |
4506 $string_keys = array_filter( $keys, 'is_string' ); |
4919 $string_keys = array_filter( $keys, 'is_string' ); |
|
4920 |
4507 return count( $string_keys ) === 0; |
4921 return count( $string_keys ) === 0; |
4508 } |
4922 } |
4509 |
4923 |
4510 /** |
4924 /** |
4511 * Filters a list of objects, based on a set of key => value arguments. |
4925 * Filters a list of objects, based on a set of key => value arguments. |
|
4926 * |
|
4927 * Retrieves the objects from the list that match the given arguments. |
|
4928 * Key represents property name, and value represents property value. |
|
4929 * |
|
4930 * If an object has more properties than those specified in arguments, |
|
4931 * that will not disqualify it. When using the 'AND' operator, |
|
4932 * any missing properties will disqualify it. |
|
4933 * |
|
4934 * When using the `$field` argument, this function can also retrieve |
|
4935 * a particular field from all matching objects, whereas wp_list_filter() |
|
4936 * only does the filtering. |
4512 * |
4937 * |
4513 * @since 3.0.0 |
4938 * @since 3.0.0 |
4514 * @since 4.7.0 Uses `WP_List_Util` class. |
4939 * @since 4.7.0 Uses `WP_List_Util` class. |
4515 * |
4940 * |
4516 * @param array $list An array of objects to filter |
4941 * @param array $list An array of objects to filter. |
4517 * @param array $args Optional. An array of key => value arguments to match |
4942 * @param array $args Optional. An array of key => value arguments to match |
4518 * against each object. Default empty array. |
4943 * against each object. Default empty array. |
4519 * @param string $operator Optional. The logical operation to perform. 'or' means |
4944 * @param string $operator Optional. The logical operation to perform. 'AND' means |
4520 * only one element from the array needs to match; 'and' |
4945 * all elements from the array must match. 'OR' means only |
4521 * means all elements must match; 'not' means no elements may |
4946 * one element needs to match. 'NOT' means no elements may |
4522 * match. Default 'and'. |
4947 * match. Default 'AND'. |
4523 * @param bool|string $field A field from the object to place instead of the entire object. |
4948 * @param bool|string $field Optional. A field from the object to place instead |
4524 * Default false. |
4949 * of the entire object. Default false. |
4525 * @return array A list of objects or object fields. |
4950 * @return array A list of objects or object fields. |
4526 */ |
4951 */ |
4527 function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) { |
4952 function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) { |
4528 if ( ! is_array( $list ) ) { |
4953 if ( ! is_array( $list ) ) { |
4529 return array(); |
4954 return array(); |
4572 * |
5008 * |
4573 * @since 3.1.0 |
5009 * @since 3.1.0 |
4574 * @since 4.0.0 $index_key parameter added. |
5010 * @since 4.0.0 $index_key parameter added. |
4575 * @since 4.7.0 Uses `WP_List_Util` class. |
5011 * @since 4.7.0 Uses `WP_List_Util` class. |
4576 * |
5012 * |
4577 * @param array $list List of objects or arrays |
5013 * @param array $list List of objects or arrays. |
4578 * @param int|string $field Field from the object to place instead of the entire object |
5014 * @param int|string $field Field from the object to place instead of the entire object. |
4579 * @param int|string $index_key Optional. Field from the object to use as keys for the new array. |
5015 * @param int|string $index_key Optional. Field from the object to use as keys for the new array. |
4580 * Default null. |
5016 * Default null. |
4581 * @return array Array of found values. If `$index_key` is set, an array of found values with keys |
5017 * @return array Array of found values. If `$index_key` is set, an array of found values with keys |
4582 * corresponding to `$index_key`. If `$index_key` is null, array keys from the original |
5018 * corresponding to `$index_key`. If `$index_key` is null, array keys from the original |
4583 * `$list` will be preserved in the results. |
5019 * `$list` will be preserved in the results. |
4584 */ |
5020 */ |
4585 function wp_list_pluck( $list, $field, $index_key = null ) { |
5021 function wp_list_pluck( $list, $field, $index_key = null ) { |
4586 $util = new WP_List_Util( $list ); |
5022 $util = new WP_List_Util( $list ); |
|
5023 |
4587 return $util->pluck( $field, $index_key ); |
5024 return $util->pluck( $field, $index_key ); |
4588 } |
5025 } |
4589 |
5026 |
4590 /** |
5027 /** |
4591 * Sorts a list of objects, based on one or more orderby arguments. |
5028 * Sorts a list of objects, based on one or more orderby arguments. |
6275 * |
6717 * |
6276 * @since 3.3.0 |
6718 * @since 3.3.0 |
6277 * @since 4.3.0 Added 'webcal' to the protocols array. |
6719 * @since 4.3.0 Added 'webcal' to the protocols array. |
6278 * @since 4.7.0 Added 'urn' to the protocols array. |
6720 * @since 4.7.0 Added 'urn' to the protocols array. |
6279 * @since 5.3.0 Added 'sms' to the protocols array. |
6721 * @since 5.3.0 Added 'sms' to the protocols array. |
|
6722 * @since 5.6.0 Added 'irc6' and 'ircs' to the protocols array. |
6280 * |
6723 * |
6281 * @see wp_kses() |
6724 * @see wp_kses() |
6282 * @see esc_url() |
6725 * @see esc_url() |
6283 * |
6726 * |
6284 * @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https', |
6727 * @return string[] Array of allowed protocols. Defaults to an array containing 'http', 'https', |
6285 * 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', |
6728 * 'ftp', 'ftps', 'mailto', 'news', 'irc', 'irc6', 'ircs', 'gopher', 'nntp', 'feed', |
6286 * 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'. |
6729 * 'telnet', 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'. |
6287 * This covers all common link protocols, except for 'javascript' which should not |
6730 * This covers all common link protocols, except for 'javascript' which should not |
6288 * be allowed for untrusted users. |
6731 * be allowed for untrusted users. |
6289 */ |
6732 */ |
6290 function wp_allowed_protocols() { |
6733 function wp_allowed_protocols() { |
6291 static $protocols = array(); |
6734 static $protocols = array(); |
6292 |
6735 |
6293 if ( empty( $protocols ) ) { |
6736 if ( empty( $protocols ) ) { |
6294 $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' ); |
6737 $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'irc6', 'ircs', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'sms', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' ); |
6295 } |
6738 } |
6296 |
6739 |
6297 if ( ! did_action( 'wp_loaded' ) ) { |
6740 if ( ! did_action( 'wp_loaded' ) ) { |
6298 /** |
6741 /** |
6299 * Filters the list of protocols allowed in HTML attributes. |
6742 * Filters the list of protocols allowed in HTML attributes. |
7068 * Filters the contents of the email notification sent when the site admin email address is changed. |
7517 * Filters the contents of the email notification sent when the site admin email address is changed. |
7069 * |
7518 * |
7070 * @since 4.9.0 |
7519 * @since 4.9.0 |
7071 * |
7520 * |
7072 * @param array $email_change_email { |
7521 * @param array $email_change_email { |
7073 * Used to build wp_mail(). |
7522 * Used to build wp_mail(). |
7074 * |
7523 * |
7075 * @type string $to The intended recipient. |
7524 * @type string $to The intended recipient. |
7076 * @type string $subject The subject of the email. |
7525 * @type string $subject The subject of the email. |
7077 * @type string $message The content of the email. |
7526 * @type string $message The content of the email. |
7078 * The following strings have a special meaning and will get replaced dynamically: |
7527 * The following strings have a special meaning and will get replaced dynamically: |
7079 * - ###OLD_EMAIL### The old site admin email address. |
7528 * - ###OLD_EMAIL### The old site admin email address. |
7080 * - ###NEW_EMAIL### The new site admin email address. |
7529 * - ###NEW_EMAIL### The new site admin email address. |
7081 * - ###SITENAME### The name of the site. |
7530 * - ###SITENAME### The name of the site. |
7082 * - ###SITEURL### The URL to the site. |
7531 * - ###SITEURL### The URL to the site. |
7083 * @type string $headers Headers. |
7532 * @type string $headers Headers. |
7084 * } |
7533 * } |
7085 * @param string $old_email The old site admin email address. |
7534 * @param string $old_email The old site admin email address. |
7086 * @param string $new_email The new site admin email address. |
7535 * @param string $new_email The new site admin email address. |
7087 */ |
7536 */ |
7088 $email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email ); |
7537 $email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email ); |
7089 |
7538 |
7472 return; |
7925 return; |
7473 } |
7926 } |
7474 |
7927 |
7475 echo '<p class="button-container">'; |
7928 echo '<p class="button-container">'; |
7476 printf( |
7929 printf( |
7477 '<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>', |
7930 '<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>', |
7478 esc_url( $direct_update_url ), |
7931 esc_url( $direct_update_url ), |
7479 __( 'Update PHP' ), |
7932 __( 'Update PHP' ), |
7480 /* translators: Accessibility text. */ |
7933 /* translators: Accessibility text. */ |
7481 __( '(opens in a new tab)' ) |
7934 __( '(opens in a new tab)' ) |
7482 ); |
7935 ); |
7483 echo '</p>'; |
7936 echo '</p>'; |
7484 } |
7937 } |
7485 |
7938 |
7486 /** |
7939 /** |
|
7940 * Gets the URL to learn more about updating the site to use HTTPS. |
|
7941 * |
|
7942 * This URL can be overridden by specifying an environment variable `WP_UPDATE_HTTPS_URL` or by using the |
|
7943 * {@see 'wp_update_https_url'} filter. Providing an empty string is not allowed and will result in the |
|
7944 * default URL being used. Furthermore the page the URL links to should preferably be localized in the |
|
7945 * site language. |
|
7946 * |
|
7947 * @since 5.7.0 |
|
7948 * |
|
7949 * @return string URL to learn more about updating to HTTPS. |
|
7950 */ |
|
7951 function wp_get_update_https_url() { |
|
7952 $default_url = wp_get_default_update_https_url(); |
|
7953 |
|
7954 $update_url = $default_url; |
|
7955 if ( false !== getenv( 'WP_UPDATE_HTTPS_URL' ) ) { |
|
7956 $update_url = getenv( 'WP_UPDATE_HTTPS_URL' ); |
|
7957 } |
|
7958 |
|
7959 /** |
|
7960 * Filters the URL to learn more about updating the HTTPS version the site is running on. |
|
7961 * |
|
7962 * Providing an empty string is not allowed and will result in the default URL being used. Furthermore |
|
7963 * the page the URL links to should preferably be localized in the site language. |
|
7964 * |
|
7965 * @since 5.7.0 |
|
7966 * |
|
7967 * @param string $update_url URL to learn more about updating HTTPS. |
|
7968 */ |
|
7969 $update_url = apply_filters( 'wp_update_https_url', $update_url ); |
|
7970 if ( empty( $update_url ) ) { |
|
7971 $update_url = $default_url; |
|
7972 } |
|
7973 |
|
7974 return $update_url; |
|
7975 } |
|
7976 |
|
7977 /** |
|
7978 * Gets the default URL to learn more about updating the site to use HTTPS. |
|
7979 * |
|
7980 * Do not use this function to retrieve this URL. Instead, use {@see wp_get_update_https_url()} when relying on the URL. |
|
7981 * This function does not allow modifying the returned URL, and is only used to compare the actually used URL with the |
|
7982 * default one. |
|
7983 * |
|
7984 * @since 5.7.0 |
|
7985 * @access private |
|
7986 * |
|
7987 * @return string Default URL to learn more about updating to HTTPS. |
|
7988 */ |
|
7989 function wp_get_default_update_https_url() { |
|
7990 /* translators: Documentation explaining HTTPS and why it should be used. */ |
|
7991 return __( 'https://wordpress.org/support/article/why-should-i-use-https/' ); |
|
7992 } |
|
7993 |
|
7994 /** |
|
7995 * Gets the URL for directly updating the site to use HTTPS. |
|
7996 * |
|
7997 * A URL will only be returned if the `WP_DIRECT_UPDATE_HTTPS_URL` environment variable is specified or |
|
7998 * by using the {@see 'wp_direct_update_https_url'} filter. This allows hosts to send users directly to |
|
7999 * the page where they can update their site to use HTTPS. |
|
8000 * |
|
8001 * @since 5.7.0 |
|
8002 * |
|
8003 * @return string URL for directly updating to HTTPS or empty string. |
|
8004 */ |
|
8005 function wp_get_direct_update_https_url() { |
|
8006 $direct_update_url = ''; |
|
8007 |
|
8008 if ( false !== getenv( 'WP_DIRECT_UPDATE_HTTPS_URL' ) ) { |
|
8009 $direct_update_url = getenv( 'WP_DIRECT_UPDATE_HTTPS_URL' ); |
|
8010 } |
|
8011 |
|
8012 /** |
|
8013 * Filters the URL for directly updating the PHP version the site is running on from the host. |
|
8014 * |
|
8015 * @since 5.7.0 |
|
8016 * |
|
8017 * @param string $direct_update_url URL for directly updating PHP. |
|
8018 */ |
|
8019 $direct_update_url = apply_filters( 'wp_direct_update_https_url', $direct_update_url ); |
|
8020 |
|
8021 return $direct_update_url; |
|
8022 } |
|
8023 |
|
8024 /** |
7487 * Get the size of a directory. |
8025 * Get the size of a directory. |
7488 * |
8026 * |
7489 * A helper function that is used primarily to check whether |
8027 * A helper function that is used primarily to check whether |
7490 * a blog has exceeded its allowed upload space. |
8028 * a blog has exceeded its allowed upload space. |
7491 * |
8029 * |
7496 * @param int $max_execution_time Maximum time to run before giving up. In seconds. |
8034 * @param int $max_execution_time Maximum time to run before giving up. In seconds. |
7497 * The timeout is global and is measured from the moment WordPress started to load. |
8035 * The timeout is global and is measured from the moment WordPress started to load. |
7498 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. |
8036 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. |
7499 */ |
8037 */ |
7500 function get_dirsize( $directory, $max_execution_time = null ) { |
8038 function get_dirsize( $directory, $max_execution_time = null ) { |
7501 $dirsize = get_transient( 'dirsize_cache' ); |
|
7502 |
|
7503 if ( is_array( $dirsize ) && isset( $dirsize[ $directory ]['size'] ) ) { |
|
7504 return $dirsize[ $directory ]['size']; |
|
7505 } |
|
7506 |
|
7507 if ( ! is_array( $dirsize ) ) { |
|
7508 $dirsize = array(); |
|
7509 } |
|
7510 |
8039 |
7511 // Exclude individual site directories from the total when checking the main site of a network, |
8040 // Exclude individual site directories from the total when checking the main site of a network, |
7512 // as they are subdirectories and should not be counted. |
8041 // as they are subdirectories and should not be counted. |
7513 if ( is_multisite() && is_main_site() ) { |
8042 if ( is_multisite() && is_main_site() ) { |
7514 $dirsize[ $directory ]['size'] = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time ); |
8043 $size = recurse_dirsize( $directory, $directory . '/sites', $max_execution_time ); |
7515 } else { |
8044 } else { |
7516 $dirsize[ $directory ]['size'] = recurse_dirsize( $directory, null, $max_execution_time ); |
8045 $size = recurse_dirsize( $directory, null, $max_execution_time ); |
7517 } |
8046 } |
7518 |
8047 |
7519 set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS ); |
8048 return $size; |
7520 return $dirsize[ $directory ]['size']; |
|
7521 } |
8049 } |
7522 |
8050 |
7523 /** |
8051 /** |
7524 * Get the size of a directory recursively. |
8052 * Get the size of a directory recursively. |
7525 * |
8053 * |
7526 * Used by get_dirsize() to get a directory's size when it contains |
8054 * Used by get_dirsize() to get a directory size when it contains other directories. |
7527 * other directories. |
|
7528 * |
8055 * |
7529 * @since MU (3.0.0) |
8056 * @since MU (3.0.0) |
7530 * @since 4.3.0 $exclude parameter added. |
8057 * @since 4.3.0 The `$exclude` parameter was added. |
7531 * @since 5.2.0 $max_execution_time parameter added. |
8058 * @since 5.2.0 The `$max_execution_time` parameter was added. |
|
8059 * @since 5.6.0 The `$directory_cache` parameter was added. |
7532 * |
8060 * |
7533 * @param string $directory Full path of a directory. |
8061 * @param string $directory Full path of a directory. |
7534 * @param string|array $exclude Optional. Full path of a subdirectory to exclude from the total, |
8062 * @param string|array $exclude Optional. Full path of a subdirectory to exclude from the total, |
7535 * or array of paths. Expected without trailing slash(es). |
8063 * or array of paths. Expected without trailing slash(es). |
7536 * @param int $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global |
8064 * @param int $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global |
7537 * and is measured from the moment WordPress started to load. |
8065 * and is measured from the moment WordPress started to load. |
|
8066 * @param array $directory_cache Optional. Array of cached directory paths. |
|
8067 * |
7538 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. |
8068 * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. |
7539 */ |
8069 */ |
7540 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null ) { |
8070 function recurse_dirsize( $directory, $exclude = null, $max_execution_time = null, &$directory_cache = null ) { |
7541 $size = 0; |
8071 $directory = untrailingslashit( $directory ); |
7542 |
8072 $save_cache = false; |
7543 $directory = untrailingslashit( $directory ); |
8073 |
|
8074 if ( ! isset( $directory_cache ) ) { |
|
8075 $directory_cache = get_transient( 'dirsize_cache' ); |
|
8076 $save_cache = true; |
|
8077 } |
|
8078 |
|
8079 if ( isset( $directory_cache[ $directory ] ) && is_int( $directory_cache[ $directory ] ) ) { |
|
8080 return $directory_cache[ $directory ]; |
|
8081 } |
7544 |
8082 |
7545 if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) { |
8083 if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) { |
7546 return false; |
8084 return false; |
7547 } |
8085 } |
7548 |
8086 |
7566 if ( $max_execution_time > 10 ) { |
8104 if ( $max_execution_time > 10 ) { |
7567 $max_execution_time -= 1; |
8105 $max_execution_time -= 1; |
7568 } |
8106 } |
7569 } |
8107 } |
7570 |
8108 |
7571 $handle = opendir( $directory ); |
8109 /** |
7572 if ( $handle ) { |
8110 * Filters the amount of storage space used by one directory and all its children, in megabytes. |
7573 while ( ( $file = readdir( $handle ) ) !== false ) { |
8111 * |
7574 $path = $directory . '/' . $file; |
8112 * Return the actual used space to short-circuit the recursive PHP file size calculation |
7575 if ( '.' !== $file && '..' !== $file ) { |
8113 * and use something else, like a CDN API or native operating system tools for better performance. |
7576 if ( is_file( $path ) ) { |
8114 * |
7577 $size += filesize( $path ); |
8115 * @since 5.6.0 |
7578 } elseif ( is_dir( $path ) ) { |
8116 * |
7579 $handlesize = recurse_dirsize( $path, $exclude, $max_execution_time ); |
8117 * @param int|false $space_used The amount of used space, in bytes. Default false. |
7580 if ( $handlesize > 0 ) { |
8118 */ |
7581 $size += $handlesize; |
8119 $size = apply_filters( 'pre_recurse_dirsize', false, $directory, $exclude, $max_execution_time, $directory_cache ); |
|
8120 |
|
8121 if ( false === $size ) { |
|
8122 $size = 0; |
|
8123 |
|
8124 $handle = opendir( $directory ); |
|
8125 if ( $handle ) { |
|
8126 while ( ( $file = readdir( $handle ) ) !== false ) { |
|
8127 $path = $directory . '/' . $file; |
|
8128 if ( '.' !== $file && '..' !== $file ) { |
|
8129 if ( is_file( $path ) ) { |
|
8130 $size += filesize( $path ); |
|
8131 } elseif ( is_dir( $path ) ) { |
|
8132 $handlesize = recurse_dirsize( $path, $exclude, $max_execution_time, $directory_cache ); |
|
8133 if ( $handlesize > 0 ) { |
|
8134 $size += $handlesize; |
|
8135 } |
|
8136 } |
|
8137 |
|
8138 if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) { |
|
8139 // Time exceeded. Give up instead of risking a fatal timeout. |
|
8140 $size = null; |
|
8141 break; |
7582 } |
8142 } |
7583 } |
8143 } |
7584 |
|
7585 if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) { |
|
7586 // Time exceeded. Give up instead of risking a fatal timeout. |
|
7587 $size = null; |
|
7588 break; |
|
7589 } |
|
7590 } |
8144 } |
7591 } |
8145 closedir( $handle ); |
7592 closedir( $handle ); |
8146 } |
7593 } |
8147 } |
|
8148 |
|
8149 $directory_cache[ $directory ] = $size; |
|
8150 |
|
8151 // Only write the transient on the top level call and not on recursive calls. |
|
8152 if ( $save_cache ) { |
|
8153 set_transient( 'dirsize_cache', $directory_cache ); |
|
8154 } |
|
8155 |
7594 return $size; |
8156 return $size; |
|
8157 } |
|
8158 |
|
8159 /** |
|
8160 * Cleans directory size cache used by recurse_dirsize(). |
|
8161 * |
|
8162 * Removes the current directory and all parent directories from the `dirsize_cache` transient. |
|
8163 * |
|
8164 * @since 5.6.0 |
|
8165 * |
|
8166 * @param string $path Full path of a directory or file. |
|
8167 */ |
|
8168 function clean_dirsize_cache( $path ) { |
|
8169 $directory_cache = get_transient( 'dirsize_cache' ); |
|
8170 |
|
8171 if ( empty( $directory_cache ) ) { |
|
8172 return; |
|
8173 } |
|
8174 |
|
8175 $path = untrailingslashit( $path ); |
|
8176 unset( $directory_cache[ $path ] ); |
|
8177 |
|
8178 while ( DIRECTORY_SEPARATOR !== $path && '.' !== $path && '..' !== $path ) { |
|
8179 $path = dirname( $path ); |
|
8180 unset( $directory_cache[ $path ] ); |
|
8181 } |
|
8182 |
|
8183 set_transient( 'dirsize_cache', $directory_cache ); |
7595 } |
8184 } |
7596 |
8185 |
7597 /** |
8186 /** |
7598 * Checks compatibility with the current WordPress version. |
8187 * Checks compatibility with the current WordPress version. |
7599 * |
8188 * |