PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.1.3
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.1.3
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 / BackupValidator.php
wp-staging / Backup Last commit date
Ajax 2 years ago BackgroundProcessing 2 years ago Dto 2 years ago Entity 2 years ago Exceptions 3 years ago Job 2 years ago Request 2 years ago Service 2 years ago Storage 2 years ago Task 2 years ago AfterRestore.php 3 years ago BackupDeleter.php 3 years ago BackupDownload.php 3 years ago BackupProcessLock.php 3 years ago BackupRepairer.php 3 years ago BackupScheduler.php 2 years ago BackupServiceProvider.php 2 years ago BackupValidator.php 2 years ago WithBackupIdentifier.php 2 years ago wpstgBackupHeader.txt 3 years ago
BackupValidator.php
213 lines
1 <?php
2
3 namespace WPStaging\Backup;
4
5 use WPStaging\Framework\Filesystem\FileObject;
6 use WPStaging\Backup\Entity\BackupMetadata;
7 use WPStaging\Backup\Exceptions\BackupRuntimeException;
8 use WPStaging\Backup\Service\BackupsFinder;
9 use WPStaging\Backup\Task\Tasks\JobRestore\RestoreRequirementsCheckTask;
10
11 use function WPStaging\functions\debug_log;
12
13 class BackupValidator
14 {
15 /** @var BackupsFinder */
16 private $backupsFinder;
17
18 /** @var array */
19 protected $missingPartIssues = [];
20
21 /** @var array */
22 protected $partSizeIssues = [];
23
24 /** @var string */
25 protected $backupDir;
26
27 /** @var array */
28 protected $existingParts = [];
29
30 /** @var string */
31 protected $error = '';
32
33 public function __construct(BackupsFinder $backupsFinder)
34 {
35 $this->partSizeIssues = [];
36 $this->missingPartIssues = [];
37 $this->backupsFinder = $backupsFinder;
38 $this->backupDir = '';
39 }
40
41 /** @return array */
42 public function getMissingPartIssues()
43 {
44 return $this->missingPartIssues;
45 }
46
47 /** @return array */
48 public function getPartSizeIssues()
49 {
50 return $this->partSizeIssues;
51 }
52
53 /** @return string */
54 public function getErrorMessage()
55 {
56 return $this->error;
57 }
58
59 /**
60 * @param FileObject $file
61 * @param BackupMetadata $metadata
62 * @return bool
63 */
64 public function validateFileIndex(FileObject $file, BackupMetadata $metadata)
65 {
66 // Early bail if not wpstg file
67 if ($file->getExtension() !== 'wpstg') {
68 return true;
69 }
70
71 $start = $metadata->getHeaderStart();
72 $end = $metadata->getHeaderEnd();
73 if ($end - $start < 4) {
74 $error = esc_html__('File Index of ' . $file->getFilename() . ' not found!', 'wp-staging');
75 debug_log($error);
76 $this->error = $error;
77
78 return false;
79 }
80
81 $file->fseek($start);
82 $lineBreaks = [
83 "\r",
84 "\n",
85 "\r\n",
86 "\n\r",
87 PHP_EOL
88 ];
89
90 $count = 0;
91 while ($file->valid() && $file->ftell() < $end) {
92 $line = $file->readAndMoveNext();
93 if (empty($line) || in_array($line, $lineBreaks)) {
94 continue;
95 }
96
97 $count++;
98 }
99
100 $totalFiles = $metadata->getTotalFiles();
101 if ($count !== $totalFiles && !$metadata->getIsMultipartBackup()) {
102 $error = sprintf(esc_html__('File Index of ' . $file->getFilename() . ' is invalid! Actual number of files in the backup index: %s. Expected number of files: %s', 'wp-staging'), $count, $totalFiles);
103 $this->error = $error;
104 debug_log($error);
105
106 return false;
107 }
108
109 if (!$metadata->getIsMultipartBackup()) {
110 return true;
111 }
112
113 $totalFiles = $metadata->getMultipartMetadata()->getTotalFiles();
114 if ($count !== $totalFiles && $metadata->getIsMultipartBackup()) {
115 $error = sprintf(esc_html__('File Index of ' . $file->getFilename() . ' multipart backup is invalid! Actual number of files in the backup index: %s. Expected number of files: %s', 'wp-staging'), $count, $totalFiles);
116 $this->error = $error;
117 debug_log($error);
118
119 return false;
120 }
121
122 return true;
123 }
124
125 /** @return bool
126 * @throws BackupRuntimeException
127 */
128 public function checkIfSplitBackupIsValid(BackupMetadata $metadata)
129 {
130 $this->partSizeIssues = [];
131 $this->missingPartIssues = [];
132
133 // Early bail if not split backup
134 if (!$metadata->getIsMultipartBackup()) {
135 return true;
136 }
137
138 $this->backupDir = wp_normalize_path($this->backupsFinder->getBackupsDirectory());
139
140 $splitMetadata = $metadata->getMultipartMetadata();
141
142 foreach ($splitMetadata->getPluginsParts() as $part) {
143 $this->validatePart($part, 'plugins');
144 }
145
146 foreach ($splitMetadata->getThemesParts() as $part) {
147 $this->validatePart($part, 'themes');
148 }
149
150 foreach ($splitMetadata->getUploadsParts() as $part) {
151 $this->validatePart($part, 'uploads');
152 }
153
154 foreach ($splitMetadata->getMuPluginsParts() as $part) {
155 $this->validatePart($part, 'muplugins');
156 }
157
158 foreach ($splitMetadata->getOthersParts() as $part) {
159 $this->validatePart($part, 'others');
160 }
161
162 foreach ($splitMetadata->getDatabaseParts() as $part) {
163 $this->validatePart($part, 'database');
164 }
165
166 return empty($this->partSizeIssues) && empty($this->missingPartIssues);
167 }
168
169 /**
170 * @param BackupMetadata $metadata
171 * @return bool
172 */
173 public function isUnsupportedBackupVersion(BackupMetadata $metadata)
174 {
175 $isCreatedOnPro = $metadata->getCreatedOnPro();
176 $version = $metadata->getWpstgVersion();
177 if (!$isCreatedOnPro) {
178 return false;
179 }
180
181 return version_compare($version, RestoreRequirementsCheckTask::BETA_VERSION_LIMIT_PRO, '<');
182 }
183
184 /**
185 * @param string $part contains part name
186 * @param string $type (plugins|themes|uploads|muplugins|others|database)
187 *
188 * @return void
189 */
190 private function validatePart($part, $type)
191 {
192 $path = $this->backupDir . str_replace($this->backupDir, '', wp_normalize_path(untrailingslashit($part)));
193 if (!file_exists($path)) {
194 $this->missingPartIssues[] = [
195 'name' => $part,
196 'type' => $type
197 ];
198
199 return;
200 }
201
202 $metadata = new BackupMetadata();
203 $metadata = $metadata->hydrateByFilePath($path);
204
205 if (filesize($path) !== $metadata->getMultipartMetadata()->getPartSize()) {
206 $this->partSizeIssues[] = $part;
207 return;
208 }
209
210 $this->existingParts[] = $part;
211 }
212 }
213