PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.3
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.3
16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / vendor / wp-php-toolkit / filesystem / Path / class-windowspath.php
jetpack / vendor / wp-php-toolkit / filesystem / Path Last commit date
class-windowspath.php 6 days ago
class-windowspath.php
126 lines
1 <?php
2 declare(strict_types=1);
3
4 namespace WordPress\Filesystem\Path;
5
6 final class WindowsPath {
7
8 private const SEP = '\\';
9
10 /** Converts every “/” to “\” so that later code can assume one separator. */
11 private static function normalize_separators( string $path ): string {
12 return str_replace( '/', self::SEP, $path );
13 }
14
15 /** Absolute = “C:\…\” or “\\server\share\…”. */
16 private static function is_absolute( string $path ): bool {
17 $path = self::normalize_separators( $path );
18 return (bool) preg_match( '/^(?:[A-Za-z]:\\\\|\\\\\\\\[^\\\\]+\\\\[^\\\\]+)/', $path );
19 }
20
21 /** Returns “C:\foo\bar” → ["C:", "foo", "bar"]; “\\srv\share\dir” → ["srv", "share", "dir"]. */
22 public static function path_segments( string $path ): array {
23 $canonical = self::canonicalize( $path );
24 $trimmed = trim( $canonical, self::SEP );
25
26 // root “C:\” or “\\srv\share\” gives empty $trimmed, keep the original string.
27 if ( '' === $trimmed ) {
28 return array( $canonical );
29 }
30 return array_values( array_filter( explode( self::SEP, $trimmed ), 'strlen' ) );
31 }
32
33 /** Joins segments with a single backslash and keeps any drive-letter or UNC prefix intact. */
34 public static function join_paths( string ...$segments ): string {
35 if ( ! $segments ) {
36 return '';
37 }
38
39 $pieces = array();
40 $first = null;
41 foreach ( $segments as $seg ) {
42 if ( '' === $seg ) {
43 continue;
44 }
45 if ( null === $first ) {
46 $first = $seg;
47 }
48 $pieces[] = trim( self::normalize_separators( $seg ), '\\/' );
49 }
50 $joined = implode( self::SEP, $pieces );
51
52 // restore UNC double backslash if needed.
53 if ( preg_match( '/^\\\\\\\\/', self::normalize_separators( $first ) ) ) {
54 return '\\\\' . ltrim( $joined, self::SEP );
55 }
56 return $joined;
57 }
58
59 /** Mirrors Node.js path.resolve for Windows rules. */
60 public static function resolve_path( string ...$segments ): string {
61 for ( $i = count( $segments ) - 1; $i >= 0; --$i ) {
62 if ( self::is_absolute( $segments[ $i ] ) ) {
63 return self::canonicalize(
64 self::join_paths( ...array_slice( $segments, $i ) )
65 );
66 }
67 }
68 array_unshift( $segments, getcwd() );
69 return self::canonicalize( self::join_paths( ...$segments ) );
70 }
71
72 /**
73 * Cleans up a path, guarantees it is absolute and free of “\.” / “\..”.
74 * Keeps trailing backslash only for drive-root (“C:\”) or UNC-root (“\\srv\share\”).
75 */
76 public static function canonicalize( string $path ): string {
77 $path = self::normalize_separators( trim( $path ) );
78
79 if ( ! self::is_absolute( $path ) ) {
80 $cwd = rtrim( getcwd(), self::SEP );
81 $path = $cwd . self::SEP . $path;
82 }
83
84 // split prefix (drive or UNC) from the rest.
85 preg_match( '/^(\\\\\\\\[^\\\\]+\\\\[^\\\\]+|[A-Za-z]:)(?:\\\\)?(.*)$/', $path, $m );
86 $prefix = $m[1] ?? '';
87 $rest = $m[2] ?? '';
88
89 $stack = array();
90 foreach ( explode( self::SEP, $rest ) as $part ) {
91 if ( '' === $part || '.' === $part ) {
92 continue;
93 }
94 if ( '..' === $part ) {
95 array_pop( $stack );
96 continue;
97 }
98 $stack[] = $part;
99 }
100
101 $resolved = $prefix;
102 if ( '' !== $resolved && self::SEP !== substr( $resolved, -1 ) ) {
103 $resolved .= self::SEP;
104 }
105 $resolved .= implode( self::SEP, $stack );
106
107 // Drive-root and UNC-root must end with “\”.
108 if ( $resolved === $prefix ) {
109 $resolved .= self::SEP;
110 }
111 return $resolved;
112 }
113
114 /** Consistent dirname() that sticks to backslashes. */
115 public static function dirname( string $path ): string {
116 $path = self::normalize_separators( $path );
117 $dir = dirname( $path );
118
119 // dirname("C:\foo") returns "C:\", keep that trailing sep; but dirname("C:\") yields "C:\".
120 if ( preg_match( '/^[A-Za-z]:$/', $dir ) ) {
121 $dir .= self::SEP;
122 }
123 return $dir;
124 }
125 }
126