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 / Backup / Service / BackupContent.php
wp-staging / Backup / Service Last commit date
Compression 1 day ago Database 1 day ago DirectoryExplorer 1 day ago AbstractBackgroundBackupRequest.php 1 day ago AbstractBackupsFinder.php 1 day ago AbstractExtractor.php 1 day ago AbstractServiceProvider.php 1 day ago Archiver.php 1 day ago BackupAssets.php 1 day ago BackupContent.php 1 day ago BackupMetadataEditor.php 1 day ago BackupMetadataReader.php 1 day ago BackupSigner.php 1 day ago BackupsDirectoryResolver.php 1 day ago BackupsFinder.php 1 day ago BeforeUpdateBackupRequest.php 1 day ago BeforeUpdateBackupsService.php 1 day ago Extractor.php 1 day ago FileBackupService.php 1 day ago FileBackupServiceProvider.php 1 day ago ServiceInterface.php 1 day ago TmpBackupCleaner.php 1 day ago UpdateProtectionHealth.php 1 day ago UpdateProtectionSettings.php 1 day ago ZlibCompressor.php 1 day ago
BackupContent.php
308 lines
1 <?php
2
3 namespace WPStaging\Backup\Service;
4
5 use WPStaging\Backup\Dto\File\BackupItemDto;
6 use WPStaging\Backup\Entity\BackupMetadata;
7 use WPStaging\Backup\Interfaces\IndexLineInterface;
8 use WPStaging\Framework\Filesystem\FileObject;
9 use WPStaging\Framework\Filesystem\PartIdentifier;
10 use WPStaging\Framework\Filesystem\PathIdentifier;
11
12
13
14
15
16
17
18
19 class BackupContent
20 {
21
22 private $backupFile = '';
23
24
25 private $totalFiles = 0;
26
27
28 private $filesFound = 0;
29
30
31 private $perPage = 20;
32
33
34 private $indexOffsetStart = 0;
35
36
37 private $indexOffsetEnd = 0;
38
39
40 private $indexPage = 0;
41
42
43 private $currentOffset = 0;
44
45
46 private $currentIndex = 0;
47
48
49 private $indexOffset = 0;
50
51
52 private $indexLineDto;
53
54
55 private $pathIdentifier;
56
57
58 private $filters = [
59 'filename' => '',
60 'sortby' => '',
61 ];
62
63
64 private $databaseFiles = [];
65
66
67
68
69
70
71
72 public function setBackup(string $backupFile, IndexLineInterface $indexLineDto, $backupMetadata = null)
73 {
74 if ($backupMetadata === null) {
75 $backupMetadata = new BackupMetadata();
76 $backupMetadata = $backupMetadata->hydrateByFilePath($backupFile);
77 }
78
79 $this->backupFile = $backupFile;
80 $this->indexLineDto = $indexLineDto;
81 $this->totalFiles = $backupMetadata->getTotalFiles();
82 $this->indexOffsetStart = $backupMetadata->getHeaderStart();
83 $this->indexOffsetEnd = $backupMetadata->getHeaderEnd();
84 }
85
86
87
88
89
90 public function setPerPage(int $perPage)
91 {
92 $this->perPage = $perPage;
93 }
94
95
96
97
98
99 public function setPathIdentifier(PathIdentifier $pathIdentifier)
100 {
101 $this->pathIdentifier = $pathIdentifier;
102 }
103
104
105
106
107
108 public function setDatabaseFiles(array $databaseFiles)
109 {
110 $this->databaseFiles = $databaseFiles;
111 }
112
113
114
115
116
117 public function setFilters(array $filters)
118 {
119 $filters['filename'] = $filters['filename'] ?? '';
120 $filters['sortby'] = $filters['sortby'] ?? '';
121
122 $this->filters = $filters;
123 }
124
125
126
127
128
129 public function setIndexOffset(int $indexOffset)
130 {
131 $this->indexOffset = $indexOffset;
132 }
133
134
135
136
137
138 public function getFiles(int $page = 1)
139 {
140 if ($page < 1) {
141 $page = 1;
142 }
143
144 $indexOffset = $this->getIndexOffset();
145 $this->indexPage = $page;
146
147 $hasFilter = !empty($this->filters['sortby']) || !empty($this->filters['filename']);
148 $maxLine = ($page - 1) * $this->perPage;
149 $objectFile = new FileObject($this->backupFile, 'rb');
150
151 $indexOffsetStart = $this->indexOffsetStart;
152
153 if (!empty($indexOffset) && !$hasFilter) {
154 $indexOffsetStart = $indexOffset;
155 }
156
157 $objectFile->fseek($indexOffsetStart);
158
159 $countLine = 0;
160 $this->filesFound = $hasFilter ? 0 : $this->totalFiles;
161 while ($objectFile->valid()) {
162 $this->currentOffset = $objectFile->ftell();
163 $this->currentIndex = $objectFile->key();
164
165 $rawIndexFile = $objectFile->readAndMoveNext();
166 if (!$this->indexLineDto->isIndexLine($rawIndexFile)) {
167 break;
168 }
169
170 $indexLineDto = $this->indexLineDto->readIndexLine($rawIndexFile);
171 $backupFile = BackupItemDto::fromIndexLineDto($indexLineDto);
172 $backupFile->setPath($this->pathIdentifier->transformIdentifiableToRelativePath($backupFile->getIdentifiablePath()));
173 $backupFile->setOffset($this->currentOffset);
174 $backupFile->setIndex($this->currentIndex);
175
176 if ($this->isFiltered($backupFile)) {
177 continue;
178 }
179
180 if ($hasFilter) {
181 $this->filesFound++;
182 }
183
184 if ($this->filesFound < $maxLine || $countLine === $this->perPage) {
185 if ($hasFilter) {
186 continue;
187 } else {
188 break;
189 }
190 }
191
192 yield $backupFile;
193 $countLine++;
194 }
195
196 $objectFile = null;
197 }
198
199
200
201
202 public function getPagingData(): array
203 {
204 return [
205 'totalIndex' => $this->filesFound,
206 'totalPage' => ceil($this->filesFound / $this->perPage),
207 'indexPage' => $this->indexPage,
208 'indexFilter' => $this->filters['filename'],
209 'indexSortby' => $this->filters['sortby'],
210 'indexOffset' => $this->getIndexOffset(),
211 'indexNextOffset' => $this->getNextOffset($this->getCurrentOffset()),
212 ];
213 }
214
215
216
217
218 public function getIndexOffset(): int
219 {
220 return $this->indexOffset;
221 }
222
223
224
225
226 public function getCurrentOffset(): int
227 {
228 return $this->currentOffset;
229 }
230
231
232
233
234
235 public function getNextOffset(int $currentOffset): int
236 {
237 $objectFile = new FileObject($this->backupFile, 'rb');
238 $objectFile->fseek($currentOffset);
239 $objectFile->readAndMoveNext();
240 $nextOffset = $objectFile->ftell();
241 $objectFile = null;
242
243 switch (true) {
244 case ($nextOffset > $this->indexOffsetEnd):
245 $nextOffset = $this->indexOffsetEnd;
246 break;
247 case (empty($nextOffset) || $nextOffset < 0):
248 $nextOffset = $this->indexOffsetStart;
249 break;
250 }
251
252 return $nextOffset;
253 }
254
255
256
257
258
259 private function isFiltered(BackupItemDto $backupFile): bool
260 {
261 if ($this->filterByName($backupFile)) {
262 return true;
263 }
264
265 return $this->filterBySortBy($backupFile);
266 }
267
268
269
270
271
272 private function filterByName(BackupItemDto $backupFile): bool
273 {
274 if (empty($this->filters['filename'])) {
275 return false;
276 }
277
278 return strpos($backupFile->getPath(), $this->filters['filename']) === false;
279 }
280
281
282
283
284
285 private function filterBySortBy(BackupItemDto $backupFile): bool
286 {
287 if (empty($this->filters['sortby'])) {
288 return false;
289 }
290
291 if ($this->filters['sortby'] === PartIdentifier::DATABASE_PART_IDENTIFIER) {
292 return !in_array($backupFile->getIdentifiablePath(), $this->databaseFiles);
293 }
294
295 if ($this->filters['sortby'] === PartIdentifier::UPLOAD_PART_IDENTIFIER && in_array($backupFile->getIdentifiablePath(), $this->databaseFiles)) {
296 return true;
297 }
298
299 if ($this->filters['sortby'] === PartIdentifier::DROPIN_PART_IDENTIFIER) {
300 return !$this->pathIdentifier->hasDropinsFile($backupFile->getIdentifiablePath());
301 }
302
303 $identifier = $this->pathIdentifier->getIdentifierByPartName($this->filters['sortby']);
304
305 return $identifier !== $this->pathIdentifier->getIdentifierFromPath($backupFile->getIdentifiablePath());
306 }
307 }
308