PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.9.4
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.9.4
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 / Traits / FileScanToCacheTrait.php
wp-staging / Framework / Traits Last commit date
ApplyFiltersTrait.php 2 months ago ArrayableTrait.php 7 months ago BatchSizeCalculateTrait.php 7 months ago BearerTokenTrait.php 5 months ago BenchmarkTrait.php 3 years ago BooleanTransientTrait.php 5 years ago DatabaseSearchReplaceTrait.php 1 month ago DbRowsGeneratorTrait.php 4 years ago DebugLogTrait.php 1 year ago DeveloperTimerTrait.php 9 months ago EndOfLinePlaceholderTrait.php 1 year ago EventLoggerTrait.php 2 months ago FileScanToCacheTrait.php 4 days ago FormatTrait.php 1 year ago HttpRequestTrait.php 9 months ago HydrateTrait.php 1 year ago I18nTrait.php 1 year ago IpResolverTrait.php 11 months ago MaintenanceTrait.php 6 months ago MemoryExhaustTrait.php 2 years ago MySQLRowsGeneratorTrait.php 7 months ago NoticesTrait.php 4 days ago PropertyConstructor.php 5 years ago RenameTmpDirectoryTrait.php 6 months ago ResourceTrait.php 5 months ago RestRequestTrait.php 4 months ago RestoreFileExclusionTrait.php 1 year ago SafeFileInfoTrait.php 4 days ago SerializeTrait.php 1 year ago SetTimeLimitTrait.php 2 months ago SlashTrait.php 1 year ago SqlCommentTrait.php 4 months ago TablePrefixValidator.php 4 months ago UrlTrait.php 1 year ago ValueGetterTrait.php 2 years ago WindowsOsTrait.php 1 year ago
FileScanToCacheTrait.php
196 lines
1 <?php
2
3 namespace WPStaging\Framework\Traits;
4
5 use Exception;
6 use RuntimeException;
7 use WPStaging\Core\Utils\Logger;
8 use WPStaging\Core\WPStaging;
9 use WPStaging\Framework\Filesystem\Filesystem;
10 use WPStaging\Framework\Filesystem\FilterableDirectoryIterator;
11 use WPStaging\Framework\Utils\Strings;
12 use WPStaging\Framework\Traits\EndOfLinePlaceholderTrait;
13 use WPStaging\Framework\Traits\SafeFileInfoTrait;
14
15 trait FileScanToCacheTrait
16 {
17 use EndOfLinePlaceholderTrait;
18 use SafeFileInfoTrait;
19
20 /** @var bool */
21 protected $isExcludedWpConfig = false;
22
23 /** @var string */
24 protected $pathIdentifier = '';
25
26 /**
27 * @var Strings
28 */
29 protected $strUtils;
30
31 /**
32 * @var Logger
33 */
34 protected $logger;
35
36 /**
37 * Write contents to a file
38 *
39 * @param resource $handle File handle to write to
40 * @param string $content Content to write to the file
41 * @return int
42 * @throws Exception
43 */
44 abstract public function write($handle, $content);
45
46 /**
47 * Scan Recursively through DirectoryIterator as RecursiveDirectoryIterator is slow
48 *
49 * @param resource $filesHandle
50 * @param string $path
51 * @param bool $isRecursive
52 * @param array $excludePaths absolute path of dir/files to exclude
53 * @param array $excludeSizeRules exclude files by different size comparing rules
54 * @param string $wpRootPath
55 * @param bool $shouldScanEmptyDirs
56 *
57 * @return int count of files path written to cache file
58 * @throws Exception
59 */
60 public function scanToCacheFile($filesHandle, $path, $isRecursive = false, $excludePaths = [], $excludeSizeRules = [], $wpRootPath = ABSPATH, bool $shouldScanEmptyDirs = true)
61 {
62 if (!is_readable($path)) {
63 $this->log(sprintf('Skipping! The path "%s" is not readable.', $path), Logger::TYPE_WARNING);
64 return 0;
65 }
66
67 $filesystem = WPStaging::make(Filesystem::class);
68 $normalizedWpRoot = $filesystem->normalizePath($wpRootPath);
69
70 if (is_file($path)) {
71 $file = str_replace($normalizedWpRoot, '', $filesystem->normalizePath($path, true));
72 $file = $this->replaceEOLsWithPlaceholders($file) . PHP_EOL;
73 if ($this->write($filesHandle, $file)) {
74 return 1;
75 }
76
77 return 0;
78 }
79
80 $filesWrittenToCache = 0;
81 try {
82 $iterator = (new FilterableDirectoryIterator())
83 ->setDirectory($filesystem->trailingSlashit($path))
84 ->setRecursive(false)
85 ->setDotSkip()
86 ->setExcludePaths($excludePaths)
87 ->setExcludeSizeRules($excludeSizeRules)
88 ->setWpRootPath($wpRootPath)
89 ->get();
90
91 foreach ($iterator as $item) {
92 // Always check link first otherwise it may be treated as directory
93 $itemPath = $item->getPathname();
94
95 $isLink = $this->isLinkSafely($item);
96 if ($isLink === null) {
97 continue;
98 }
99
100 if ($isLink) {
101 // Allow copying of link if the link's source is a directory
102 $linkTarget = $this->getRealPathSafely($item);
103 if ($linkTarget !== false && is_dir($linkTarget) && $isRecursive) {
104 $filesWrittenToCache += $this->scanToCacheFile($filesHandle, $itemPath, $isRecursive, $excludePaths, $excludeSizeRules, $wpRootPath, $shouldScanEmptyDirs);
105 }
106
107 continue;
108 }
109
110 if ($isRecursive) {
111 $isDir = $this->isDirSafely($item);
112 if ($isDir === null) {
113 continue;
114 }
115
116 if ($isDir) {
117 $filesWrittenToCache += $this->scanToCacheFile($filesHandle, $itemPath, $isRecursive, $excludePaths, $excludeSizeRules, $wpRootPath, $shouldScanEmptyDirs);
118 continue;
119 }
120 }
121
122 $isFile = $this->isFileSafely($item);
123 if ($isFile === null) {
124 continue;
125 }
126
127 if ($isFile) {
128 $file = $filesystem->maybeNormalizePath($itemPath);
129 $file = $this->strUtils->replaceStartWith($normalizedWpRoot, '', $file);
130 // One more time with not normalized $wpRootPath in case the file path was not normalized
131 $file = $this->strUtils->replaceStartWith($wpRootPath, '', $file);
132
133 // At the moment will only handle case where wp-config.php is present at root folder of WP
134 if ($file === '/wp-config.php') {
135 $this->setIsExcludedWpConfig(false);
136 }
137
138 $file = $this->replaceEOLsWithPlaceholders($file) . PHP_EOL;
139 if ($this->write($filesHandle, $this->pathIdentifier . ltrim($file, '/'))) {
140 $filesWrittenToCache++;
141 }
142 }
143 }
144 } catch (Exception $e) {
145 throw new RuntimeException($e->getMessage());
146 }
147
148 if ($shouldScanEmptyDirs && $filesWrittenToCache === 0 && is_dir($path)) {
149 $pathPart = $this->strUtils->replaceStartWith($normalizedWpRoot, '', $path) . PHP_EOL;
150 $this->write($filesHandle, $this->pathIdentifier . ltrim($pathPart, '/'));
151 $filesWrittenToCache++;
152 }
153
154 return $filesWrittenToCache;
155 }
156
157 /**
158 * @param bool $skipped
159 */
160 public function setIsExcludedWpConfig($skipped = true)
161 {
162 $this->isExcludedWpConfig = $skipped;
163 }
164
165 /**
166 * @return bool
167 */
168 public function getIsExcludedWpConfig()
169 {
170 return $this->isExcludedWpConfig;
171 }
172
173 /**
174 * @param string $pathIdentifier
175 */
176 protected function setPathIdentifier($pathIdentifier)
177 {
178 $this->pathIdentifier = $pathIdentifier;
179 }
180
181 /**
182 * @param string $msg
183 * @param string $type
184 *
185 * @return void
186 */
187 public function log($msg, $type = Logger::TYPE_INFO)
188 {
189 if ($this->logger === null) {
190 $this->logger = WPStaging::make(Logger::class);
191 }
192
193 $this->logger->add($msg, $type);
194 }
195 }
196