PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.0
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.0
4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Filesystem / AbstractFilesystemScanner.php
wp-staging / Framework / Filesystem Last commit date
Filters 1 day ago Scanning 1 day ago AbstractFileObject.php 1 day ago AbstractFilesystemScanner.php 1 day ago DebugLogReader.php 1 day ago DirectoryListing.php 1 day ago DirectorySize.php 1 day ago DiskWriteCheck.php 1 day ago FileObject.php 1 day ago Filesystem.php 1 day ago FilesystemExceptions.php 5 years ago FilesystemScanner.php 1 day ago FilesystemScannerDto.php 1 day ago FilterableDirectoryIterator.php 1 day ago LegacyFileRulesTrait.php 1 day ago LogCleanup.php 1 day ago LogFiles.php 1 day ago MissingFileException.php 3 years ago OPcache.php 1 day ago PartIdentifier.php 1 day ago PathChecker.php 1 day ago PathIdentifier.php 1 day ago Permissions.php 1 day ago WpUploadsFolderSymlinker.php 1 day ago
AbstractFilesystemScanner.php
372 lines
1 <?php
2
3 namespace WPStaging\Framework\Filesystem;
4
5 use Exception;
6 use SplFileInfo;
7 use WPStaging\Framework\Adapter\Directory;
8 use WPStaging\Framework\Traits\EndOfLinePlaceholderTrait;
9 use WPStaging\Framework\Traits\SafeFileInfoTrait;
10 use WPStaging\Framework\Utils\PluginInfo;
11
12 abstract class AbstractFilesystemScanner
13 {
14 use EndOfLinePlaceholderTrait;
15 use SafeFileInfoTrait;
16
17
18
19
20 const PATH_SEPARATOR = '::';
21
22
23 protected $directory;
24
25
26 protected $filesystem;
27
28
29 protected $pathIdentifier;
30
31
32 protected $pluginInfo;
33
34
35
36
37
38
39
40 protected $currentPathScanning = '';
41
42
43
44
45
46 protected $rootPath = '';
47
48
49
50
51
52 protected $contentPath = '';
53
54
55 protected $skipFiles = false;
56
57
58 protected $skipDirectories = false;
59
60
61 protected $excludeRules = [];
62
63
64
65
66
67
68
69 public function __construct(
70 Directory $directory,
71 PathIdentifier $pathIdentifier,
72 Filesystem $filesystem,
73 PluginInfo $pluginInfo
74 ) {
75 $this->directory = $directory;
76 $this->filesystem = $filesystem;
77 $this->pathIdentifier = $pathIdentifier;
78 $this->pluginInfo = $pluginInfo;
79 $this->rootPath = ABSPATH;
80 $this->contentPath = WP_CONTENT_DIR;
81 }
82
83
84
85
86
87 public function setCurrentPathScanning(string $currentPathScanning)
88 {
89 $this->currentPathScanning = $currentPathScanning;
90 }
91
92
93
94
95
96 public function setRootPath(string $rootPath)
97 {
98 $this->rootPath = $rootPath;
99 }
100
101
102
103
104
105 public function setContentPath(string $contentPath)
106 {
107 $this->contentPath = $contentPath;
108 }
109
110
111
112
113 public function setOnlyFiles()
114 {
115 $this->skipFiles = false;
116 $this->skipDirectories = true;
117 }
118
119
120
121
122 public function setOnlyDirectories()
123 {
124 $this->skipFiles = true;
125 $this->skipDirectories = false;
126 }
127
128 public function resetFilesDirectoriesSkipping()
129 {
130 $this->skipFiles = false;
131 $this->skipDirectories = false;
132 }
133
134
135
136
137
138 public function setExcludeRules(array $excludeRules)
139 {
140 $this->excludeRules = $excludeRules;
141 }
142
143
144
145
146
147 public function addExcludeRule(string $excludeRule)
148 {
149 $this->excludeRules[] = $excludeRule;
150 }
151
152
153
154
155
156
157
158 public function preScanPath(string $directory, bool $processLinks = false, bool $scanLinkDirectory = true)
159 {
160 $iterator = (new FilterableDirectoryIterator())
161 ->setDirectory(trailingslashit($directory))
162 ->setRecursive(false)
163 ->setSkipDirectoriesWithIncludeRules()
164 ->setDotSkip()
165 ->setWpRootPath($this->rootPath)
166 ->setExcludePaths($this->excludeRules)
167 ->get();
168
169
170 foreach ($iterator as $item) {
171 $isLink = $this->isLinkSafely($item);
172 if ($isLink === null) {
173 continue;
174 }
175
176 if ($isLink && $processLinks) {
177 $this->processLink($item, $scanLinkDirectory);
178 }
179
180 if ($isLink) {
181 continue;
182 }
183
184 $isFile = $this->isFileSafely($item);
185 if ($isFile === null) {
186 continue;
187 }
188
189 if ($isFile && !$this->skipFiles) {
190 $this->processFile($item);
191 }
192
193 if ($isFile) {
194 continue;
195 }
196
197 if ($this->skipDirectories) {
198 continue;
199 }
200
201 $isDir = $this->isDirSafely($item);
202 if ($isDir) {
203 $this->processDirectory($item);
204 }
205 }
206 }
207
208
209
210
211
212
213 protected function processPath(string $path)
214 {
215 $path = $this->replacePlaceholdersWithEOLs($path);
216 if (empty($path)) {
217 return;
218 }
219
220 list($path, $linkPath) = $this->resolvePath($path);
221
222 $path = untrailingslashit($this->filesystem->normalizePath($path, true));
223
224 if (!file_exists($path)) {
225 throw new Exception("$path is not a directory. Skipping...");
226 }
227
228 $this->preRecursivePathScanningStep();
229 $this->recursivePathScanning($path, $linkPath);
230 }
231
232
233
234
235 abstract protected function preRecursivePathScanningStep();
236
237
238
239
240
241
242 abstract protected function processFile(SplFileInfo $fileInfo, string $linkPath = '');
243
244
245
246
247
248
249 abstract protected function processDirectory(SplFileInfo $fileInfo, $linkInfo = null);
250
251
252
253
254
255
256 protected function processLink(SplFileInfo $linkInfo, bool $scanDirectory = true)
257 {
258 $isLink = $this->isLinkSafely($linkInfo);
259 if ($isLink === null || !$isLink) {
260 return;
261 }
262
263 $linkTarget = $this->getRealPathSafely($linkInfo);
264 if ($linkTarget === false) {
265 return;
266 }
267
268 $fileInfo = new SplFileInfo($linkTarget);
269
270 $isLink = $this->isLinkSafely($fileInfo);
271 if ($isLink === null || $isLink) {
272 return;
273 }
274
275 $isFile = $this->isFileSafely($fileInfo);
276 if ($isFile === null) {
277 return;
278 }
279
280 if ($isFile) {
281 $this->processFile($fileInfo, $linkInfo->getPathname());
282 return;
283 }
284
285 $isDir = $this->isDirSafely($fileInfo);
286 if ($isDir && $scanDirectory) {
287 $this->processDirectory($fileInfo, $linkInfo);
288 return;
289 }
290 }
291
292
293
294
295
296
297
298
299
300
301 protected function resolvePath(string $pathToResolve): array
302 {
303 $linkPath = '';
304 $pathInfos = explode(self::PATH_SEPARATOR, $pathToResolve);
305
306
307 if (count($pathInfos) > 2) {
308
309 $linkPath = $pathInfos[2];
310 }
311
312
313 $this->currentPathScanning = $pathInfos[0];
314
315
316 $path = $pathInfos[1];
317
318 return [$path, $linkPath];
319 }
320
321
322
323
324
325
326
327
328
329 protected function recursivePathScanning(string $path, string $link = '')
330 {
331 $iterator = (new FilterableDirectoryIterator())
332 ->setDirectory(trailingslashit($path))
333 ->setRecursive(false)
334 ->setDotSkip()
335 ->setWpRootPath($this->rootPath)
336 ->get();
337
338
339 foreach ($iterator as $item) {
340 $isLink = $this->isLinkSafely($item);
341 if ($isLink === null) {
342 continue;
343 }
344
345
346 if ($isLink) {
347 continue;
348 }
349
350 $linkPath = '';
351 if (!empty($link)) {
352 $linkPath = trailingslashit($link) . $item->getFilename();
353 }
354
355 $isDir = $this->isDirSafely($item);
356 if ($isDir === null) {
357 continue;
358 }
359
360 if ($isDir) {
361 $this->recursivePathScanning($item->getPathname(), $linkPath);
362 continue;
363 }
364
365 $isFile = $this->isFileSafely($item);
366 if ($isFile) {
367 $this->processFile($item, $linkPath);
368 }
369 }
370 }
371 }
372