PluginProbe ʕ •ᴥ•ʔ
10Web Booster – Website speed optimization, Cache & Page Speed optimizer / trunk
10Web Booster – Website speed optimization, Cache & Page Speed optimizer vtrunk
2.33.6 2.33.5 2.33.0 2.30.5 2.30.7 2.30.9 2.31.10 2.31.8 2.32.11 2.32.21 2.32.3 2.32.4 2.32.7 2.6.31 2.6.40 2.6.42 2.6.7 2.7.37 2.7.44 2.7.47 2.8.18 2.8.19 2.8.32 2.8.34 2.8.35 2.9.23 2.9.24 2.9.25 2.9.27 v2.27.4 trunk 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.17 2.0.18 2.0.21 2.0.22 2.0.25 2.0.26 2.0.27 2.0.3 2.0.7 2.0.9 2.10.46 2.10.65 2.10.66 2.10.68 2.11.41 2.11.42 2.11.43 2.12.15 2.12.21 2.12.22 2.12.23 2.12.26 2.13.37 2.13.40 2.13.41 2.13.42 2.13.44 2.13.45 2.13.47 2.14.49 2.14.50 2.15.18 2.17.21 2.17.23 2.18.17 2.19.44 2.19.45 2.19.46 2.19.49 2.2.12 2.2.15 2.2.16 2.2.18 2.2.8 2.20.31 2.20.32 2.20.33 2.21.11 2.21.12 2.21.16 2.21.25 2.22.32 2.23.13 2.23.15 2.23.16 2.23.18 2.24.12 2.24.14 2.24.18 2.25.14 2.26.6 2.28.10 2.28.13 2.28.14 2.28.7 2.29.1 2.29.2 2.29.3 2.3.0 2.3.1 2.3.2 2.3.3 2.30.18
tenweb-speed-optimizer / vendor / matthiasmullie / path-converter / src / Converter.php
tenweb-speed-optimizer / vendor / matthiasmullie / path-converter / src Last commit date
Converter.php 4 years ago ConverterInterface.php 4 years ago NoConverter.php 4 years ago
Converter.php
205 lines
1 <?php
2
3 namespace MatthiasMullie\PathConverter;
4
5 /**
6 * Convert paths relative from 1 file to another.
7 *
8 * E.g.
9 * ../../images/icon.jpg relative to /css/imports/icons.css
10 * becomes
11 * ../images/icon.jpg relative to /css/minified.css
12 *
13 * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
14 *
15 * @author Matthias Mullie <pathconverter@mullie.eu>
16 * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
17 * @license MIT License
18 */
19 class Converter implements ConverterInterface
20 {
21 /**
22 * @var string
23 */
24 protected $from;
25
26 /**
27 * @var string
28 */
29 protected $to;
30
31 /**
32 * @param string $from The original base path (directory, not file!)
33 * @param string $to The new base path (directory, not file!)
34 * @param string $root Root directory (defaults to `getcwd`)
35 */
36 public function __construct($from, $to, $root = '')
37 {
38 $shared = $this->shared($from, $to);
39 if ($shared === '') {
40 // when both paths have nothing in common, one of them is probably
41 // absolute while the other is relative
42 $root = $root ?: getcwd();
43 $from = strpos($from, $root) === 0 ? $from : preg_replace('/\/+/', '/', $root.'/'.$from);
44 $to = strpos($to, $root) === 0 ? $to : preg_replace('/\/+/', '/', $root.'/'.$to);
45
46 // or traveling the tree via `..`
47 // attempt to resolve path, or assume it's fine if it doesn't exist
48 $from = @realpath($from) ?: $from;
49 $to = @realpath($to) ?: $to;
50 }
51
52 $from = $this->dirname($from);
53 $to = $this->dirname($to);
54
55 $from = $this->normalize($from);
56 $to = $this->normalize($to);
57
58 $this->from = $from;
59 $this->to = $to;
60 }
61
62 /**
63 * Normalize path.
64 *
65 * @param string $path
66 *
67 * @return string
68 */
69 protected function normalize($path)
70 {
71 // deal with different operating systems' directory structure
72 $path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
73
74 // remove leading current directory.
75 if (substr($path, 0, 2) === './') {
76 $path = substr($path, 2);
77 }
78
79 // remove references to current directory in the path.
80 $path = str_replace('/./', '/', $path);
81
82 /*
83 * Example:
84 * /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif
85 * to
86 * /home/forkcms/frontend/core/layout/images/img.gif
87 */
88 do {
89 $path = preg_replace('/[^\/]+(?<!\.\.)\/\.\.\//', '', $path, -1, $count);
90 } while ($count);
91
92 return $path;
93 }
94
95 /**
96 * Figure out the shared path of 2 locations.
97 *
98 * Example:
99 * /home/forkcms/frontend/core/layout/images/img.gif
100 * and
101 * /home/forkcms/frontend/cache/minified_css
102 * share
103 * /home/forkcms/frontend
104 *
105 * @param string $path1
106 * @param string $path2
107 *
108 * @return string
109 */
110 protected function shared($path1, $path2)
111 {
112 // $path could theoretically be empty (e.g. no path is given), in which
113 // case it shouldn't expand to array(''), which would compare to one's
114 // root /
115 $path1 = $path1 ? explode('/', $path1) : array();
116 $path2 = $path2 ? explode('/', $path2) : array();
117
118 $shared = array();
119
120 // compare paths & strip identical ancestors
121 foreach ($path1 as $i => $chunk) {
122 if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
123 $shared[] = $chunk;
124 } else {
125 break;
126 }
127 }
128
129 return implode('/', $shared);
130 }
131
132 /**
133 * Convert paths relative from 1 file to another.
134 *
135 * E.g.
136 * ../images/img.gif relative to /home/forkcms/frontend/core/layout/css
137 * should become:
138 * ../../core/layout/images/img.gif relative to
139 * /home/forkcms/frontend/cache/minified_css
140 *
141 * @param string $path The relative path that needs to be converted
142 *
143 * @return string The new relative path
144 */
145 public function convert($path)
146 {
147 // quit early if conversion makes no sense
148 if ($this->from === $this->to) {
149 return $path;
150 }
151
152 $path = $this->normalize($path);
153 // if we're not dealing with a relative path, just return absolute
154 if (strpos($path, '/') === 0) {
155 return $path;
156 }
157
158 // normalize paths
159 $path = $this->normalize($this->from.'/'.$path);
160
161 // strip shared ancestor paths
162 $shared = $this->shared($path, $this->to);
163 $path = mb_substr($path, mb_strlen($shared));
164 $to = mb_substr($this->to, mb_strlen($shared));
165
166 // add .. for every directory that needs to be traversed to new path
167 $to = str_repeat('../', count(array_filter(explode('/', $to))));
168
169 return $to.ltrim($path, '/');
170 }
171
172 /**
173 * Attempt to get the directory name from a path.
174 *
175 * @param string $path
176 *
177 * @return string
178 */
179 protected function dirname($path)
180 {
181 if (@is_file($path)) {
182 return dirname($path);
183 }
184
185 if (@is_dir($path)) {
186 return rtrim($path, '/');
187 }
188
189 // no known file/dir, start making assumptions
190
191 // ends in / = dir
192 if (mb_substr($path, -1) === '/') {
193 return rtrim($path, '/');
194 }
195
196 // has a dot in the name, likely a file
197 if (preg_match('/.*\..*$/', basename($path)) !== 0) {
198 return dirname($path);
199 }
200
201 // you're on your own here!
202 return $path;
203 }
204 }
205