Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
89.74% |
35 / 39 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
| Boost_Cache_Utils | |
89.74% |
35 / 39 |
|
80.00% |
4 / 5 |
18.35 | |
0.00% |
0 / 1 |
| deep_replace | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
| trailingslashit | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| sanitize_file_path | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
1 | |||
| normalize_request_uri | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
10 | |||
| is_visible_post_type | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
| 1 | <?php |
| 2 | /* |
| 3 | * This file may be called before WordPress is fully initialized. See the README file for info. |
| 4 | */ |
| 5 | |
| 6 | namespace Automattic\Jetpack_Boost\Modules\Optimizations\Page_Cache\Pre_WordPress; |
| 7 | |
| 8 | use WP_Post; |
| 9 | |
| 10 | class Boost_Cache_Utils { |
| 11 | |
| 12 | /** |
| 13 | * Performs a deep string replace operation to ensure the values in $search are no longer present. |
| 14 | * Copied from wp-includes/formatting.php |
| 15 | * |
| 16 | * Repeats the replacement operation until it no longer replaces anything to remove "nested" values |
| 17 | * e.g. $subject = '%0%0%0DDD', $search ='%0D', $result ='' rather than the '%0%0DD' that |
| 18 | * str_replace would return |
| 19 | * |
| 20 | * @param string|array $search The value being searched for, otherwise known as the needle. |
| 21 | * An array may be used to designate multiple needles. |
| 22 | * @param string $subject The string being searched and replaced on, otherwise known as the haystack. |
| 23 | * @return string The string with the replaced values. |
| 24 | */ |
| 25 | public static function deep_replace( $search, $subject ) { |
| 26 | $subject = (string) $subject; |
| 27 | |
| 28 | $count = 1; |
| 29 | while ( $count ) { |
| 30 | $subject = str_replace( $search, '', $subject, $count ); |
| 31 | } |
| 32 | |
| 33 | return $subject; |
| 34 | } |
| 35 | |
| 36 | public static function trailingslashit( $string ) { |
| 37 | return rtrim( $string, '/' ) . '/'; |
| 38 | } |
| 39 | |
| 40 | /** |
| 41 | * Returns a sanitized directory path. |
| 42 | * |
| 43 | * @param string $path - The path to sanitize. |
| 44 | * @return string |
| 45 | */ |
| 46 | public static function sanitize_file_path( $path ) { |
| 47 | $path = self::trailingslashit( $path ); |
| 48 | $path = self::deep_replace( |
| 49 | array( '..', '\\' ), |
| 50 | preg_replace( |
| 51 | '/[ <>\'\"\r\n\t\(\)]/', |
| 52 | '', |
| 53 | preg_replace( |
| 54 | '/(\?.*)?(#.*)?$/', |
| 55 | '', |
| 56 | $path |
| 57 | ) |
| 58 | ) |
| 59 | ); |
| 60 | |
| 61 | return $path; |
| 62 | } |
| 63 | |
| 64 | /** |
| 65 | * Normalize a request path, removing its query and adding a trailing slash except for existing files. |
| 66 | * This does not sanitize filesystem paths; use it only for comparisons or cache keys. |
| 67 | * |
| 68 | * @param string $request_uri - The request uri to normalize. |
| 69 | * @return string|false The normalized request uri, or false if it is not a valid cacheable path. |
| 70 | */ |
| 71 | public static function normalize_request_uri( $request_uri ) { |
| 72 | if ( ! is_string( $request_uri ) ) { |
| 73 | return false; |
| 74 | } |
| 75 | if ( 0 === strpos( $request_uri, '/' ) ) { |
| 76 | $request_uri = '/' . ltrim( $request_uri, '/' ); |
| 77 | } |
| 78 | if ( false !== strpos( $request_uri, '#' ) ) { |
| 79 | return false; |
| 80 | } |
| 81 | $raw_path = explode( '?', $request_uri, 2 )[0]; |
| 82 | $request_uri = parse_url( $raw_path, PHP_URL_PATH ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url |
| 83 | if ( false === $request_uri || (string) $request_uri !== $raw_path ) { |
| 84 | return false; |
| 85 | } |
| 86 | if ( '' === $request_uri || null === $request_uri ) { |
| 87 | $request_uri = '/'; |
| 88 | } elseif ( substr( $request_uri, -1 ) !== '/' && ! is_file( ABSPATH . $request_uri ) ) { |
| 89 | $request_uri .= '/'; |
| 90 | } |
| 91 | |
| 92 | return $request_uri; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Checks if the post type is public. |
| 97 | * |
| 98 | * @param WP_Post $post - The post to check. |
| 99 | * @return bool - True if the post type is public. |
| 100 | */ |
| 101 | public static function is_visible_post_type( $post ) { |
| 102 | $post_type = is_a( $post, 'WP_Post' ) ? get_post_type_object( $post->post_type ) : null; |
| 103 | if ( empty( $post_type ) || ! $post_type->public ) { |
| 104 | return false; |
| 105 | } |
| 106 | return true; |
| 107 | } |
| 108 | } |