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 / Filesystem / LegacyFileRulesTrait.php
wp-staging / Framework / Filesystem Last commit date
Filters 2 days ago Scanning 5 years ago AbstractFileObject.php 1 year ago AbstractFilesystemScanner.php 2 days ago DebugLogReader.php 2 years ago DirectoryListing.php 6 months ago DirectorySize.php 2 weeks ago DiskWriteCheck.php 6 months ago FileObject.php 1 year ago Filesystem.php 7 months ago FilesystemExceptions.php 5 years ago FilesystemScanner.php 2 weeks ago FilesystemScannerDto.php 1 month ago FilterableDirectoryIterator.php 1 year ago LegacyFileRulesTrait.php 2 weeks ago LogCleanup.php 6 months ago LogFiles.php 1 year ago MissingFileException.php 3 years ago OPcache.php 6 months ago PartIdentifier.php 9 months ago PathChecker.php 2 years ago PathIdentifier.php 3 weeks ago Permissions.php 1 month ago WpUploadsFolderSymlinker.php 1 month ago
LegacyFileRulesTrait.php
215 lines
1 <?php
2
3 namespace WPStaging\Framework\Filesystem;
4
5 /**
6 * Normalizes and evaluates legacy file exclusion rules, so scanners and size estimates
7 * agree on which files and folders the copy leaves out.
8 */
9 trait LegacyFileRulesTrait
10 {
11 /**
12 * True when the copy would skip this file: by name rule, extension, or size limit.
13 *
14 * @param string $path
15 * @param string[] $excludedExtensions Lowercase extensions (e.g. "log").
16 * @param string[] $fileNameRules Rules in "position value" form (e.g. "name_ends_with .bak").
17 * @param int $maxFileSizeBytes Files bigger than this are excluded; 0 disables the limit.
18 * @return bool
19 */
20 protected function isExcludedFileByRules(string $path, array $excludedExtensions, array $fileNameRules, int $maxFileSizeBytes): bool
21 {
22 $name = basename($path);
23
24 foreach ($fileNameRules as $rule) {
25 if ($this->ruleMatch($rule, $name)) {
26 return true;
27 }
28 }
29
30 if (in_array(strtolower(pathinfo($name, PATHINFO_EXTENSION)), $excludedExtensions, true)) {
31 return true;
32 }
33
34 if ($maxFileSizeBytes > 0) {
35 $size = filesize($path);
36 if ($size !== false && $size > $maxFileSizeBytes) {
37 return true;
38 }
39 }
40
41 return false;
42 }
43
44 /**
45 * True when the copy would skip this folder by a folder name rule.
46 *
47 * @param string $path
48 * @param string[] $folderNameRules Rules in "position value" form.
49 * @return bool
50 */
51 protected function isExcludedFolderByRules(string $path, array $folderNameRules): bool
52 {
53 $name = basename($path);
54 foreach ($folderNameRules as $rule) {
55 if ($this->ruleMatch($rule, $name)) {
56 return true;
57 }
58 }
59
60 return false;
61 }
62
63 /**
64 * @param array $fileRules
65 * @return array
66 */
67 protected function extractLegacyFileNameRules(array $fileRules): array
68 {
69 $normalizedRules = [];
70
71 foreach ($fileRules as $fileRule) {
72 if (!is_string($fileRule)) {
73 continue;
74 }
75
76 $fileRule = trim($fileRule);
77 if ($fileRule === '') {
78 continue;
79 }
80
81 $fileRule = $this->reduceLegacyPathRuleToFileName($fileRule);
82
83 if ($fileRule !== '') {
84 $normalizedRules[] = $fileRule;
85 }
86 }
87
88 return array_values(array_unique($normalizedRules));
89 }
90
91 /**
92 * @param array $fileRules
93 * @return array
94 */
95 protected function extractFileExtensions(array $fileRules): array
96 {
97 $extensions = [];
98
99 foreach ($fileRules as $fileRule) {
100 if (!is_string($fileRule)) {
101 continue;
102 }
103
104 $fileRule = trim($fileRule);
105 if ($this->getLegacyVcsDirectoryName($fileRule) !== '') {
106 continue;
107 }
108
109 // Only glob extension rules (`*.log`) exclude by extension; a filename rule like
110 // `wp-staging-optimizer.php` must not turn `.php` into an ignored extension.
111 if (strpos($fileRule, '*.') !== 0) {
112 continue;
113 }
114
115 $fileRule = ltrim($fileRule, '*');
116 $position = strrpos($fileRule, '.');
117 if ($position === false || $position === strlen($fileRule) - 1) {
118 continue;
119 }
120
121 $extension = strtolower(substr($fileRule, $position + 1));
122 if ($extension !== '') {
123 $extensions[] = $extension;
124 }
125 }
126
127 return array_values(array_unique($extensions));
128 }
129
130 /**
131 * @param array $fileRules
132 * @return array
133 */
134 protected function extractLegacyFolderNameRules(array $fileRules): array
135 {
136 $folderRules = [];
137
138 foreach ($fileRules as $fileRule) {
139 if (!is_string($fileRule)) {
140 continue;
141 }
142
143 $vcsDirectoryName = $this->getLegacyVcsDirectoryName($fileRule);
144 if ($vcsDirectoryName === '') {
145 continue;
146 }
147
148 $folderRules[] = 'name_exact_matches ' . $vcsDirectoryName;
149 }
150
151 return array_values(array_unique($folderRules));
152 }
153
154 /**
155 * Matches a "position value" rule (e.g. "name_ends_with .bak") against a file or folder name.
156 *
157 * @param string $rule
158 * @param string $name
159 * @return bool
160 */
161 protected function ruleMatch(string $rule, string $name): bool
162 {
163 $rule = trim($rule);
164 if (strpos($rule, ' ') === false) {
165 return false;
166 }
167
168 list($ruleType, $ruleValue) = explode(' ', $rule, 2);
169 switch ($ruleType) {
170 case 'name_contains':
171 return strpos($name, $ruleValue) !== false;
172 case 'name_begins_with':
173 return strpos($name, $ruleValue) === 0;
174 case 'name_ends_with':
175 return substr($name, -strlen($ruleValue)) === $ruleValue;
176 case 'name_exact_matches':
177 return $name === $ruleValue;
178 default:
179 return false;
180 }
181 }
182
183 private function getLegacyVcsDirectoryName(string $fileRule): string
184 {
185 $fileRule = trim($fileRule);
186 if ($fileRule === '') {
187 return '';
188 }
189
190 $fileRule = strtolower($this->reduceLegacyPathRuleToFileName($fileRule));
191 if (strpos($fileRule, '*.') === 0) {
192 $directoryName = substr($fileRule, 2);
193 } elseif (strpos($fileRule, '.') === 0) {
194 $directoryName = substr($fileRule, 1);
195 } else {
196 return '';
197 }
198
199 if (!in_array($directoryName, ['git', 'svn', 'hg'], true)) {
200 return '';
201 }
202
203 return '.' . $directoryName;
204 }
205
206 private function reduceLegacyPathRuleToFileName(string $fileRule): string
207 {
208 if (strpos($fileRule, '/') !== false || strpos($fileRule, '\\') !== false) {
209 return basename(str_replace('\\', '/', $fileRule));
210 }
211
212 return $fileRule;
213 }
214 }
215